C#生成唯一值的方法汇总

生成唯一值的方法很多,下面就不同环境下生成的唯一标识方法一一介绍,作为工作中的一次总结,有兴趣的可以自行测试:

一、在 .NET 中生成

1、直接用.NET Framework 提供的 Guid() 函数,此种方法使用非常广泛。GUID(全局统一标识符)是指在一台机器上生成的数字,它保证对在同一时空中的任何两台计算机都不会生成重复的 GUID 值(即保证所有机器都是唯一的)。关于GUID的介绍在此不作具体熬述,想深入了解可以自行查阅MSDN。代码如下:

C#生成唯一值的方法汇总
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 namespace ConsoleApplication1
 6 {
 7     class Program
 8     {
 9         static void Main(string[] args)
10         {
11             string _guid = GetGuid();
12             Console.WriteLine("唯一码:{0}\t长度为:{1}\n去掉连接符:{2}", _guid, _guid.Length, _guid.Replace("-", ""));
13             string uniqueIdString = GuidTo16String();
14             Console.WriteLine("唯一码:{0}\t长度为:{1}", uniqueIdString, uniqueIdString.Length);
15             long uniqueIdLong = GuidToLongID();
16             Console.WriteLine("唯一码:{0}\t长度为:{1}", uniqueIdLong, uniqueIdLong.ToString().Length);
17         }
18         /// <summary>
19         /// 由连字符分隔的32位数字
20         /// </summary>
21         /// <returns></returns>
22         private static string GetGuid()
23         {
24             System.Guid guid = new Guid();
25             guid = Guid.NewGuid();
26             return guid.ToString();
27         }
28         /// <summary>  
29         /// 根据GUID获取16位的唯一字符串  
30         /// </summary>  
31         /// <param name=\"guid\"></param>  
32         /// <returns></returns>  
33         public static string GuidTo16String()
34         {
35             long i = 1;
36             foreach (byte b in Guid.NewGuid().ToByteArray())
37                 i *= ((int)b + 1);
38             return string.Format("{0:x}", i - DateTime.Now.Ticks);
39         }
40         /// <summary>  
41         /// 根据GUID获取19位的唯一数字序列  
42         /// </summary>  
43         /// <returns></returns>  
44         public static long GuidToLongID()
45         {
46             byte[] buffer = Guid.NewGuid().ToByteArray();
47             return BitConverter.ToInt64(buffer, 0);
48         }   
49     }
50 }
View Code

 

 

2、用 DateTime.Now.ToString("yyyyMMddHHmmssms") 和 .NET Framework 提供的 RNGCryptoServiceProvider() 结合生成,代码如下:

C#生成唯一值的方法汇总
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 namespace ConsoleApplication1
 7 {
 8     class Program
 9     {
10         static void Main(string[] args)
11         {
12             string uniqueNum = GenerateOrderNumber();
13             Console.WriteLine("唯一码:{0}\t 长度为:{1}", uniqueNum, uniqueNum.Length);
14             //测试是否会生成重复
15               Console.WriteLine("时间+RNGCryptoServiceProvider()结合生成的唯一值,如下:");
16             string _tempNum = string.Empty;
17             for (int i = 0; i < 1000; i++)
18             {
19                 string uNum = GenerateOrderNumber();
20                 Console.WriteLine(uNum);
21                 if (string.Equals(uNum, _tempNum))
22                 {
23                     Console.WriteLine("上值存在重复,按Enter键继续");
24                     Console.ReadKey();
25                 }
26                 //Sleep当前线程,是为了延时,从而不产生重复值。可以把它注释掉测试看
27                 Thread.Sleep(300);
28                 _tempNum = uNum;
29             }
30         }
31         /// <summary>
32         /// 唯一订单号生成
33         /// </summary>
34         /// <returns></returns>
35         public static string GenerateOrderNumber()
36         {
37             string strDateTimeNumber = DateTime.Now.ToString("yyyyMMddHHmmssms");
38             string strRandomResult = NextRandom(1000, 1).ToString();
39             return strDateTimeNumber + strRandomResult;
40         }
41         /// <summary>
42         /// 参考:msdn上的RNGCryptoServiceProvider例子
43         /// </summary>
44         /// <param name="numSeeds"></param>
45         /// <param name="length"></param>
46         /// <returns></returns>
47         private static int NextRandom(int numSeeds, int length)
48         {
49             // Create a byte array to hold the random value.  
50             byte[] randomNumber = new byte[length];
51             // Create a new instance of the RNGCryptoServiceProvider.  
52             System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
53             // Fill the array with a random value.  
54             rng.GetBytes(randomNumber);
55             // Convert the byte to an uint value to make the modulus operation easier.  
56             uint randomResult = 0x0;
57             for (int i = 0; i < length; i++)
58             {
59                 randomResult |= ((uint)randomNumber[i] << ((length - 1 - i) * 8));
60             }
61             return (int)(randomResult % numSeeds) + 1;
62         }
63     }
64 }
View Code

 

 

3、用 [0-9A-Z] + Guid.NewGuid() 结合生成特定位数的唯一字符串,代码如下:

C#生成唯一值的方法汇总
 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 namespace ConsoleApplication1
 6 { 
 7     class Program
 8     {
 9         static void Main(string[] args)
10         {
11             string uniqueText = GenerateUniqueText(8);
12             Console.WriteLine("唯一码:{0}\t 长度为:{1}", uniqueText, uniqueText.Length);
13             //测试是否会生成重复 
14               Console.WriteLine("由[0-9A-Z] + NewGuid() 结合生成的唯一值,如下:");
15             IList<string> list = new List<string>();
16             for (int i = 1; i <= 1000; i++)
17             {
18                 string _uT = GenerateUniqueText(8);
19                 Console.WriteLine("{0}\t{1}", list.Count, _uT);
20                 if (list.Contains(_uT))
21                 {
22                     Console.WriteLine("{0}值存在重复", _uT);
23                     Console.ReadKey();
24                 }
25                 list.Add(_uT);
26                 //if (i % 200 == 0)
27                 //{
28                     //Console.WriteLine("没有重复,按Enter键往下看");
29                     //Console.ReadKey();
30                 //}
31             }
32             list.Clear();
33         }
34 
35         /// <summary>
36         /// 生成特定位数的唯一字符串
37         /// </summary>
38         /// <param name="num">特定位数</param>
39         /// <returns></returns>
40         public static string GenerateUniqueText(int num)
41         {
42             string randomResult = string.Empty;
43             string readyStr = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
44             char[] rtn = new char[num];
45             Guid gid = Guid.NewGuid();
46             var ba = gid.ToByteArray();
47             for (var i = 0; i < num; i++)
48             {
49                 rtn[i] = readyStr[((ba[i] + ba[num + i]) % 35)];
50             }
51             foreach (char r in rtn)
52             {
53                 randomResult += r;
54             }
55             return randomResult;
56         }
57     }
58 }
View Code

 

 

 

4、用单例模式实现,由[0-9a-z]组合生成的唯一值,此文不讨论单例模式的多种实现方式与性能问题,随便弄一种方式实现,代码如下:

Demo结构如图: C#生成唯一值的方法汇总

Program.cs 程序:

C#生成唯一值的方法汇总
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Collections;
  6 using System.Xml;
  7 namespace ConsoleApplication4
  8 {
  9     class Program
 10     {
 11         static void Main(string[] args)
 12         {
 13             CreateID createID = CreateID.GetInstance();
 14             //测试是否会生成重复 
 15             Console.WriteLine("单例模式实现,由[0-9a-z]组合生成的唯一值,如下:");
 16             IList<string> list = new List<string>();
 17             for (int i = 1; i <= 1000000000; i++)
 18             {
 19                 string strUniqueNum = createID.CreateUniqueID();
 20                 Console.WriteLine("{0}\t{1}", list.Count, strUniqueNum);
 21                 if (list.Contains(strUniqueNum))
 22                 {
 23                     Console.WriteLine("{0}值存在重复", strUniqueNum);
 24                     Console.ReadKey();
 25                 }
 26                 list.Add(strUniqueNum);
 27                 if (i % 200 == 0)
 28                 {
 29                     Console.WriteLine("没有重复,按Enter键往下看");
 30                     Console.ReadKey();
 31                 }
 32             }
 33             list.Clear();
 34         }
 35     }
 36     /// <summary>
 37     /// 单例模式实现
 38     /// 唯一值由[0-9a-z]组合而成,且生成的每个ID不能重复
 39     /// </summary>
 40     public class CreateID
 41     {
 42         private static CreateID _instance;
 43         private static readonly object syncRoot = new object();
 44         private EHashtable hashtable = new EHashtable();
 45         private string _strXMLURL = string.Empty;
 46         private CreateID()
 47         {
 48             hashtable.Add("0", "0");
 49             hashtable.Add("1", "1");
 50             hashtable.Add("2", "2");
 51             hashtable.Add("3", "3");
 52             hashtable.Add("4", "4");
 53             hashtable.Add("5", "5");
 54             hashtable.Add("6", "6");
 55             hashtable.Add("7", "7");
 56             hashtable.Add("8", "8");
 57             hashtable.Add("9", "9");
 58             hashtable.Add("10", "a");
 59             hashtable.Add("11", "b");
 60             hashtable.Add("12", "c");
 61             hashtable.Add("13", "d");
 62             hashtable.Add("14", "e");
 63             hashtable.Add("15", "f");
 64             hashtable.Add("16", "g");
 65             hashtable.Add("17", "h");
 66             hashtable.Add("18", "i");
 67             hashtable.Add("19", "j");
 68             hashtable.Add("20", "k");
 69             hashtable.Add("21", "l");
 70             hashtable.Add("22", "m");
 71             hashtable.Add("23", "n");
 72             hashtable.Add("24", "o");
 73             hashtable.Add("25", "p");
 74             hashtable.Add("26", "q");
 75             hashtable.Add("27", "r");
 76             hashtable.Add("28", "s");
 77             hashtable.Add("29", "t");
 78             hashtable.Add("30", "u");
 79             hashtable.Add("31", "v");
 80             hashtable.Add("32", "w");
 81             hashtable.Add("33", "x");
 82             hashtable.Add("34", "y");
 83             hashtable.Add("35", "z");
 84             _strXMLURL = System.IO.Path.GetFullPath(@"..\..\") + "XMLs\\record.xml";
 85 
 86         }
 87         public static CreateID GetInstance()
 88         {
 89             if (_instance == null)
 90             {
 91                 lock (syncRoot)
 92                 {
 93                     if (_instance == null)
 94                     {
 95                         _instance = new CreateID();
 96                     }
 97                 }
 98             }
 99             return _instance;
100         }
101         /// <summary>
102         /// 创建UniqueID
103         /// </summary>
104         /// <returns>UniqueID</returns>
105         public string CreateUniqueID()
106         {
107             long _uniqueid = GetGuidFromXml();
108             return Convert10To36(_uniqueid);
109         }
110         /// <summary>
111         /// 获取UniqueID总记录,即获取得到的这个ID是第几个ID
112         /// 更新UniqueID使用的个数,用于下次使用
113         /// </summary>
114         /// <returns></returns>
115         private long GetGuidFromXml()
116         {
117             long record = 0;
118             XmlDocument xmldoc = new XmlDocument();
119             xmldoc.Load(_strXMLURL);
120             XmlElement rootNode = xmldoc.DocumentElement;
121             //此次的个数值
122             record = Convert.ToInt64(rootNode["record"].InnerText);
123             //此次的个数值+1 == 下次的个数值
124             rootNode["record"].InnerText = Convert.ToString(record + 1);
125             xmldoc.Save(_strXMLURL);
126             return record;
127         }
128         /// <summary>
129         /// 10进制转36进制
130         /// </summary>
131         /// <param name="intNum10">10进制数</param>
132         /// <returns></returns>
133         private string Convert10To36(long intNum10)
134         {
135             string strNum36 = string.Empty;
136             long result = intNum10 / 36;
137             long remain = intNum10 % 36;
138             if (hashtable.ContainsKey(remain.ToString()))
139                 strNum36 = hashtable[remain.ToString()].ToString() + strNum36;
140             intNum10 = result;
141             while (intNum10 / 36 != 0)
142             {
143                 result = intNum10 / 36;
144                 remain = intNum10 % 36;
145                 if (hashtable.ContainsKey(remain.ToString()))
146                     strNum36 = hashtable[remain.ToString()].ToString() + strNum36;
147                 intNum10 = result;
148             }
149             if (intNum10 > 0 && intNum10 < 36)
150             {
151                 if (hashtable.ContainsKey(intNum10.ToString()))
152                     strNum36 = hashtable[intNum10.ToString()].ToString() + strNum36;
153             }
154             return strNum36;
155         }
156     }
157     /// <summary>
158     /// Summary description for EHashTable
159     /// </summary>
160     public class EHashtable : Hashtable
161     {
162         private ArrayList list = new ArrayList();
163         public override void Add(object key, object value)
164         {
165             base.Add(key, value);
166             list.Add(key);
167         }
168         public override void Clear()
169         {
170             base.Clear();
171             list.Clear();
172         }
173         public override void Remove(object key)
174         {
175             base.Remove(key);
176             list.Remove(key);
177         }
178         public override ICollection Keys
179         {
180             get
181             {
182                 return list;
183             }
184         }
185     }
186 }
View Code

 

 

XML:

C#生成唯一值的方法汇总
1 <?xml version="1.0" encoding="utf-8"?>
2 <root>
3   <record id="record">1</record>
4 </root>
View Code

 

 

二、在JS中生成GUID,类似.NET中的 Guid.NewGuid(),代码如下:

 

C#生成唯一值的方法汇总
 1 function newGuid() { //方法一:
 2     var guid = "";
 3     var n = (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
 4     for (var i = 1; i <= 8; i++) {
 5         guid += n;
 6     }
 7     return guid;
 8 }
 9 function newGuid() { //方法二:
10     var guid = "";
11     for (var i = 1; i <= 32; i++) {
12         var n = Math.floor(Math.random() * 16.0).toString(16);
13         guid += n;
14         if ((i == 8) || (i == 12) || (i == 16) || (i == 20))
15             guid += "-";
16     }
17     return guid;
18 }
View Code

 

三、在SQL存储过程生成GUID,代码如下:

C#生成唯一值的方法汇总
 1 -- =============================================
 2 -- Author:      JBen
 3 -- Create date: 2012-06-05
 4 -- Description: 生成唯一标识ID,公共存储过程,可设置在别的存储过程调用此存储过程传不同的前缀
 5 -- =============================================
 6 ALTER PROCEDURE [dbo].[pro_CreateGuid] 
 7     @Prefix NVARCHAR(10),
 8     @outputV_guid NVARCHAR(40) OUTPUT
 9 AS
10 BEGIN
11     -- SET NOCOUNT ON added to prevent extra result sets from
12     -- interfering with SELECT statements.
13     SET NOCOUNT ON;
14     -- Insert statements for procedure here
15     SET @outputV_guid = @Prefix + REPLACE(CAST(NEWID() AS VARCHAR(36)),-,‘‘)
16 END
View Code

 

C#生成唯一值的方法汇总

上一篇:Spark API编程动手实战-08-基于IDEA使用Spark API开发Spark程序-02


下一篇:C#中Monitor和Lock以及区别