C#生成唯一值的方法汇总
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C#⽣成唯⼀值的⽅法汇总
⽣成唯⼀值的⽅法很多,下⾯就不同环境下⽣成的唯⼀标识⽅法⼀⼀介绍,作为⼯作中的⼀次总结,有兴趣的可以⾃⾏测试:
⼀、在 .NET 中⽣成
1、直接⽤.NET Framework 提供的 Guid() 函数,此种⽅法使⽤⾮常⼴泛。
GUID(全局统⼀标识符)是指在⼀台机器上⽣成的数字,它保证对在同⼀时空中的任何两台计算机都不会⽣成重复的 GUID 值(即保证所有机器都是唯⼀的)。
关于GUID的介绍在此不作具体熬述,想深⼊了解可以⾃⾏查阅MSDN。
代码如下:
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5namespace ConsoleApplication1
6 {
7class Program
8 {
9static void Main(string[] args)
10 {
11string _guid = GetGuid();
12 Console.WriteLine("唯⼀码:{0}\t长度为:{1}\n去掉连接符:{2}", _guid, _guid.Length, _guid.Replace("-", ""));
13string uniqueIdString = GuidTo16String();
14 Console.WriteLine("唯⼀码:{0}\t长度为:{1}", uniqueIdString, uniqueIdString.Length);
15long uniqueIdLong = GuidToLongID();
16 Console.WriteLine("唯⼀码:{0}\t长度为:{1}", uniqueIdLong, uniqueIdLong.ToString().Length);
17 }
18///<summary>
19///由连字符分隔的32位数字
20///</summary>
21///<returns></returns>
22private static string GetGuid()
23 {
24 System.Guid guid = new Guid();
25 guid = Guid.NewGuid();
26return guid.ToString();
27 }
28///<summary>
29///根据GUID获取16位的唯⼀字符串
30///</summary>
31///<param name=\"guid\"></param>
32///<returns></returns>
33public static string GuidTo16String()
34 {
35long i = 1;
36foreach (byte b in Guid.NewGuid().ToByteArray())
37 i *= ((int)b + 1);
38return string.Format("{0:x}", i - DateTime.Now.Ticks);
39 }
40///<summary>
41///根据GUID获取19位的唯⼀数字序列
42///</summary>
43///<returns></returns>
44public static long GuidToLongID()
45 {
46byte[] buffer = Guid.NewGuid().ToByteArray();
47return BitConverter.ToInt64(buffer, 0);
48 }
49 }
50 }
View Code
2、⽤ DateTime.Now.ToString("yyyyMMddHHmmssms") 和 .NET Framework 提供的 RNGCryptoServiceProvider() 结合⽣成,代码如下:
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Threading;
6namespace ConsoleApplication1
7 {
8class Program
9 {
10static void Main(string[] args)
11 {
12string uniqueNum = GenerateOrderNumber();
13 Console.WriteLine("唯⼀码:{0}\t 长度为:{1}", uniqueNum, uniqueNum.Length);
14//测试是否会⽣成重复
15 Console.WriteLine("时间+RNGCryptoServiceProvider()结合⽣成的唯⼀值,如下:");
16string _tempNum = string.Empty;
17for (int i = 0; i < 1000; i++)
18 {
19string uNum = GenerateOrderNumber();
20 Console.WriteLine(uNum);
21if (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>
35public static string GenerateOrderNumber()
36 {
37string strDateTimeNumber = DateTime.Now.ToString("yyyyMMddHHmmssms");
38string strRandomResult = NextRandom(1000, 1).ToString();
39return strDateTimeNumber + strRandomResult;
40 }
41///<summary>
42///参考:msdn上的RNGCryptoServiceProvider例⼦
43///</summary>
44///<param name="numSeeds"></param>
45///<param name="length"></param>
46///<returns></returns>
47private static int NextRandom(int numSeeds, int length)
48 {
49// Create a byte array to hold the random value.
50byte[] 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.
56uint randomResult = 0x0;
57for (int i = 0; i < length; i++)
58 {
59 randomResult |= ((uint)randomNumber[i] << ((length - 1 - i) * 8));
60 }
61return (int)(randomResult % numSeeds) + 1;
62 }
63 }
64 }
View Code
3、⽤ [0-9A-Z] + Guid.NewGuid() 结合⽣成特定位数的唯⼀字符串,代码如下:
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5namespace ConsoleApplication1
6 {
7class Program
8 {
9static void Main(string[] args)
10 {
11string 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>();
16for (int i = 1; i <= 1000; i++)
17 {
18string _uT = GenerateUniqueText(8);
19 Console.WriteLine("{0}\t{1}", list.Count, _uT);
20if (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>
40public static string GenerateUniqueText(int num)
41 {
42string randomResult = string.Empty;
43string readyStr = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
44char[] rtn = new char[num];
45 Guid gid = Guid.NewGuid();
46var ba = gid.ToByteArray();
47for (var i = 0; i < num; i++)
48 {
49 rtn[i] = readyStr[((ba[i] + ba[num + i]) % 35)];
50 }
51foreach (char r in rtn)
52 {
53 randomResult += r;
54 }
55return randomResult;
56 }
57 }
58 }
View Code
4、⽤单例模式实现,由[0-9a-z]组合⽣成的唯⼀值,此⽂不讨论单例模式的多种实现⽅式与性能问题,随便弄⼀种⽅式实现,代码如下:Demo结构如图:
Program.cs 程序:
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.Collections;
6using System.Xml;
7namespace ConsoleApplication4
8 {
9class Program
10 {
11static void Main(string[] args)
12 {
13 CreateID createID = CreateID.GetInstance();
14//测试是否会⽣成重复
15 Console.WriteLine("单例模式实现,由[0-9a-z]组合⽣成的唯⼀值,如下:");
16 IList<string> list = new List<string>();
17for (int i = 1; i <= 1000000000; i++)
18 {
19string strUniqueNum = createID.CreateUniqueID();
20 Console.WriteLine("{0}\t{1}", list.Count, strUniqueNum);
21if (list.Contains(strUniqueNum))
22 {
23 Console.WriteLine("{0}值存在重复", strUniqueNum);
24 Console.ReadKey();
25 }
26 list.Add(strUniqueNum);
27if (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>
40public class CreateID
41 {
42private static CreateID _instance;
43private static readonly object syncRoot = new object();
44private EHashtable hashtable = new EHashtable();
45private string _strXMLURL = string.Empty;
46private 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 }
87public static CreateID GetInstance()
88 {
89if (_instance == null)
90 {
91lock (syncRoot)
92 {
93if (_instance == null)
94 {
95 _instance = new CreateID();
96 }
97 }
98 }
99return _instance;
100 }
101///<summary>
102///创建UniqueID
103///</summary>
104///<returns>UniqueID</returns>
105public string CreateUniqueID()
106 {
107long _uniqueid = GetGuidFromXml();
108return Convert10To36(_uniqueid);
109 }
110///<summary>
111///获取UniqueID总记录,即获取得到的这个ID是第⼏个ID
112///更新UniqueID使⽤的个数,⽤于下次使⽤
113///</summary>
114///<returns></returns>
115private long GetGuidFromXml()
116 {
117long 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);
126return record;
127 }
128///<summary>
129/// 10进制转36进制
130///</summary>
131///<param name="intNum10">10进制数</param>
132///<returns></returns>
133private string Convert10To36(long intNum10)
134 {
135string strNum36 = string.Empty;
136long result = intNum10 / 36;
137long remain = intNum10 % 36;
138if (hashtable.ContainsKey(remain.ToString()))
139 strNum36 = hashtable[remain.ToString()].ToString() + strNum36;
140 intNum10 = result;
141while (intNum10 / 36 != 0)
142 {
143 result = intNum10 / 36;
144 remain = intNum10 % 36;
145if (hashtable.ContainsKey(remain.ToString()))
146 strNum36 = hashtable[remain.ToString()].ToString() + strNum36; 147 intNum10 = result;
148 }
149if (intNum10 > 0 && intNum10 < 36)
150 {
151if (hashtable.ContainsKey(intNum10.ToString()))
152 strNum36 = hashtable[intNum10.ToString()].ToString() + strNum36; 153 }
154return strNum36;
155 }
156 }
157///<summary>
158/// Summary description for EHashTable
159///</summary>
160public class EHashtable : Hashtable
161 {
162private ArrayList list = new ArrayList();
163public override void Add(object key, object value)
164 {
165base.Add(key, value);
166 list.Add(key);
167 }
168public override void Clear()
169 {
170base.Clear();
171 list.Clear();
172 }
173public override void Remove(object key)
174 {
175base.Remove(key);
176 list.Remove(key);
177 }
178public override ICollection Keys
179 {
180get
181 {
182return list;
183 }
184 }
185 }
186 }
View Code
XML:
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(),代码如下:
1function newGuid() { //⽅法⼀:
2var guid = "";
3var n = (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
4for (var i = 1; i <= 8; i++) {
5 guid += n;
6 }
7return guid;
8 }
9function newGuid() { //⽅法⼆:
10var guid = "";
11for (var i = 1; i <= 32; i++) {
12var n = Math.floor(Math.random() * 16.0).toString(16);
13 guid += n;
14if ((i == 8) || (i == 12) || (i == 16) || (i == 20))
15 guid += "-";
16 }
17return guid;
18 }
View Code
三、在SQL存储过程⽣成GUID,代码如下:
1-- =============================================
2-- Author: JBen
3-- Create date: 2012-06-05
4-- Description: ⽣成唯⼀标识ID,公共存储过程,可设置在别的存储过程调⽤此存储过程传不同的前缀 5-- =============================================
6ALTER PROCEDURE[dbo].[pro_CreateGuid]
7@Prefix NVARCHAR(10),
8@outputV_guid NVARCHAR(40) OUTPUT
9AS
10BEGIN
11-- SET NOCOUNT ON added to prevent extra result sets from
12-- interfering with SELECT statements.
13SET NOCOUNT ON;
14-- Insert statements for procedure here
15SET@outputV_guid=@Prefix+REPLACE(CAST(NEWID() AS VARCHAR(36)),'-','')
16END
View Code。