C#生成唯一值的方法汇总
生成唯一值的方法很多,下面就不同环境下生成的唯一标识方法一一介绍,作为工作中的一次总结,有兴趣的可以自行测试:
一、在.NET中生成
1、直接用.NETFramework提供的Guid()函数,此种方法使用非常广泛。GUID(全局统一标识符)是指在一台机器上生成的数字,它保证对在同一时空中的任何两台计算机都不会生成重复的GUID值(即保证所有机器都是唯一的)。关于GUID的介绍在此不作具体熬述,想深入了解可以自行查阅MSDN。代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespaceConsoleApplication1
{
classProgram
{
staticvoidMain(string[]args)
{
string_guid=GetGuid();
Console.WriteLine("唯一码:{0}\t长度为:{1}\n去掉连接符:{2}",_guid,_guid.Length,_guid.Replace("-",""));
stringuniqueIdString=GuidTo16String();
Console.WriteLine("唯一码:{0}\t长度为:{1}",uniqueIdString,uniqueIdString.Length);
longuniqueIdLong=GuidToLongID();
Console.WriteLine("唯一码:{0}\t长度为:{1}",uniqueIdLong,uniqueIdLong.ToString().Length);
}
///<summary>
///由连字符分隔的32位数字
///</summary>
///<returns></returns>
privatestaticstringGetGuid()
{
System.Guidguid=newGuid();
guid=Guid.NewGuid();
returnguid.ToString();
}
///<summary>
///根据GUID获取16位的唯一字符串
///</summary>
///<paramname=\"guid\"></param>
///<returns></returns>
publicstaticstringGuidTo16String()
{
longi=1;
foreach(bytebinGuid.NewGuid().ToByteArray())
i*=((int)b+1);
returnstring.Format("{0:x}",i-DateTime.Now.Ticks);
}
///<summary>
///根据GUID获取19位的唯一数字序列
///</summary>
///<returns></returns>
publicstaticlongGuidToLongID()
{
byte[]buffer=Guid.NewGuid().ToByteArray();
returnBitConverter.ToInt64(buffer,0);
}
}
}
2、用DateTime.Now.ToString("yyyyMMddHHmmssms")和.NETFramework提供的RNGCryptoServiceProvider()结合生成,代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Threading;
namespaceConsoleApplication1
{
classProgram
{
staticvoidMain(string[]args)
{
stringuniqueNum=GenerateOrderNumber();
Console.WriteLine("唯一码:{0}\t长度为:{1}",uniqueNum,uniqueNum.Length);
//测试是否会生成重复
Console.WriteLine("时间+RNGCryptoServiceProvider()结合生成的唯一值,如下:");
string_tempNum=string.Empty;
for(inti=0;i<1000;i++)
{
stringuNum=GenerateOrderNumber();
Console.WriteLine(uNum);
if(string.Equals(uNum,_tempNum))
{
Console.WriteLine("上值存在重复,按Enter键继续");
Console.ReadKey();
}
//Sleep当前线程,是为了延时,从而不产生重复值。可以把它注释掉测试看
Thread.Sleep(300);
_tempNum=uNum;
}
}
///<summary>
///唯一订单号生成
///</summary>
///<returns></returns>
publicstaticstringGenerateOrderNumber()
{
stringstrDateTimeNumber=DateTime.Now.ToString("yyyyMMddHHmmssms");
stringstrRandomResult=NextRandom(1000,1).ToString();
returnstrDateTimeNumber+strRandomResult;
}
///<summary>
///参考:msdn上的RNGCryptoServiceProvider例子
///</summary>
///<paramname="numSeeds"></param>
///<paramname="length"></param>
///<returns></returns>
privatestaticintNextRandom(intnumSeeds,intlength)
{
//Createabytearraytoholdtherandomvalue.
byte[]randomNumber=newbyte[length];
//CreateanewinstanceoftheRNGCryptoServiceProvider.
System.Security.Cryptography.RNGCryptoServiceProviderrng=newSystem.Security.Cryptography.RNGCryptoServiceProvider();
//Fillthearraywitharandomvalue.
rng.GetBytes(randomNumber);
//Convertthebytetoanuintvaluetomakethemodulusoperationeasier.
uintrandomResult=0x0;
for(inti=0;i<length;i++)
{
randomResult|=((uint)randomNumber[i]<<((length-1-i)*8));
}
return(int)(randomResult%numSeeds)+1;
}
}
}
3、用[0-9A-Z]+Guid.NewGuid()结合生成特定位数的唯一字符串,代码如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespaceConsoleApplication1
{
classProgram
{
staticvoidMain(string[]args)
{
stringuniqueText=GenerateUniqueText(8);
Console.WriteLine("唯一码:{0}\t长度为:{1}",uniqueText,uniqueText.Length);
//测试是否会生成重复
Console.WriteLine("由[0-9A-Z]+NewGuid()结合生成的唯一值,如下:");
IList<string>list=newList<string>();
for(inti=1;i<=1000;i++)
{
string_uT=GenerateUniqueText(8);
Console.WriteLine("{0}\t{1}",list.Count,_uT);
if(list.Contains(_uT))
{
Console.WriteLine("{0}值存在重复",_uT);
Console.ReadKey();
}
list.Add(_uT);
//if(i%200==0)
//{
//Console.WriteLine("没有重复,按Enter键往下看");
//Console.ReadKey();
//}
}
list.Clear();
}
///<summary>
///生成特定位数的唯一字符串
///</summary>
///<paramname="num">特定位数</param>
///<returns></returns>
publicstaticstringGenerateUniqueText(intnum)
{
stringrandomResult=string.Empty;
stringreadyStr="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[]rtn=newchar[num];
Guidgid=Guid.NewGuid();
varba=gid.ToByteArray();
for(vari=0;i<num;i++)
{
rtn[i]=readyStr[((ba[i]+ba[num+i])%35)];
}
foreach(charrinrtn)
{
randomResult+=r;
}
returnrandomResult;
}
}
}
4、用单例模式实现,由[0-9a-z]组合生成的唯一值,此文不讨论单例模式的多种实现方式与性能问题,随便弄一种方式实现,代码如下:
Demo结构如图:
Program.cs程序:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Collections;
usingSystem.Xml;
namespaceConsoleApplication4
{
classProgram
{
staticvoidMain(string[]args)
{
CreateIDcreateID=CreateID.GetInstance();
//测试是否会生成重复
Console.WriteLine("单例模式实现,由[0-9a-z]组合生成的唯一值,如下:");
IList<string>list=newList<string>();
for(inti=1;i<=1000000000;i++)
{
stringstrUniqueNum=createID.CreateUniqueID();
Console.WriteLine("{0}\t{1}",list.Count,strUniqueNum);
if(list.Contains(strUniqueNum))
{
Console.WriteLine("{0}值存在重复",strUniqueNum);
Console.ReadKey();
}
list.Add(strUniqueNum);
if(i%200==0)
{
Console.WriteLine("没有重复,按Enter键往下看");
Console.ReadKey();
}
}
list.Clear();
}
}
///<summary>
///单例模式实现
///唯一值由[0-9a-z]组合而成,且生成的每个ID不能重复
///</summary>
publicclassCreateID
{
privatestaticCreateID_instance;
privatestaticreadonlyobjectsyncRoot=newobject();
privateEHashtablehashtable=newEHashtable();
privatestring_strXMLURL=string.Empty;
privateCreateID()
{
hashtable.Add("0","0");
hashtable.Add("1","1");
hashtable.Add("2","2");
hashtable.Add("3","3");
hashtable.Add("4","4");
hashtable.Add("5","5");
hashtable.Add("6","6");
hashtable.Add("7","7");
hashtable.Add("8","8");
hashtable.Add("9","9");
hashtable.Add("10","a");
hashtable.Add("11","b");
hashtable.Add("12","c");
hashtable.Add("13","d");
hashtable.Add("14","e");
hashtable.Add("15","f");
hashtable.Add("16","g");
hashtable.Add("17","h");
hashtable.Add("18","i");
hashtable.Add("19","j");
hashtable.Add("20","k");
hashtable.Add("21","l");
hashtable.Add("22","m");
hashtable.Add("23","n");
hashtable.Add("24","o");
hashtable.Add("25","p");
hashtable.Add("26","q");
hashtable.Add("27","r");
hashtable.Add("28","s");
hashtable.Add("29","t");
hashtable.Add("30","u");
hashtable.Add("31","v");
hashtable.Add("32","w");
hashtable.Add("33","x");
hashtable.Add("34","y");
hashtable.Add("35","z");
_strXMLURL=System.IO.Path.GetFullPath(@"..\..\")+"XMLs\\record.xml";
}
publicstaticCreateIDGetInstance()
{
if(_instance==null)
{
lock(syncRoot)
{
if(_instance==null)
{
_instance=newCreateID();
}
}
}
return_instance;
}
///<summary>
///创建UniqueID
///</summary>
///<returns>UniqueID</returns>
publicstringCreateUniqueID()
{
long_uniqueid=GetGuidFromXml();
returnConvert10To36(_uniqueid);
}
///<summary>
///获取UniqueID总记录,即获取得到的这个ID是第几个ID
///更新UniqueID使用的个数,用于下次使用
///</summary>
///<returns></returns>
privatelongGetGuidFromXml()
{
longrecord=0;
XmlDocumentxmldoc=newXmlDocument();
xmldoc.Load(_strXMLURL);
XmlElementrootNode=xmldoc.DocumentElement;
//此次的个数值
record=Convert.ToInt64(rootNode["record"].InnerText);
//此次的个数值+1==下次的个数值
rootNode["record"].InnerText=Convert.ToString(record+1);
xmldoc.Save(_strXMLURL);
returnrecord;
}
///<summary>
///10进制转36进制
///</summary>
///<paramname="intNum10">10进制数</param>
///<returns></returns>
privatestringConvert10To36(longintNum10)
{
stringstrNum36=string.Empty;
longresult=intNum10/36;
longremain=intNum10%36;
if(hashtable.ContainsKey(remain.ToString()))
strNum36=hashtable[remain.ToString()].ToString()+strNum36;
intNum10=result;
while(intNum10/36!=0)
{
result=intNum10/36;
remain=intNum10%36;
if(hashtable.ContainsKey(remain.ToString()))
strNum36=hashtable[remain.ToString()].ToString()+strNum36;
intNum10=result;
}
if(intNum10>0&&intNum10<36)
{
if(hashtable.ContainsKey(intNum10.ToString()))
strNum36=hashtable[intNum10.ToString()].ToString()+strNum36;
}
returnstrNum36;
}
}
///<summary>
///SummarydescriptionforEHashTable
///</summary>
publicclassEHashtable:Hashtable
{
privateArrayListlist=newArrayList();
publicoverridevoidAdd(objectkey,objectvalue)
{
base.Add(key,value);
list.Add(key);
}
publicoverridevoidClear()
{
base.Clear();
list.Clear();
}
publicoverridevoidRemove(objectkey)
{
base.Remove(key);
list.Remove(key);
}
publicoverrideICollectionKeys
{
get
{
returnlist;
}
}
}
}
XML:
<?xmlversion="1.0"encoding="utf-8"?>
<root>
<recordid="record">1</record>
</root>
二、在JS中生成GUID,类似.NET中的Guid.NewGuid(),代码如下:
functionnewGuid(){//方法二: 三、在SQL存储过程生成GUID,代码如下: --Insertstatementsforprocedurehere
functionnewGuid(){//方法一:
varguid="";
varn=(((1+Math.random())*0x10000)|0).toString(16).substring(1);
for(vari=1;i<=8;i++){
guid+=n;
}
returnguid;
}
varguid="";
for(vari=1;i<=32;i++){
varn=Math.floor(Math.random()*16.0).toString(16);
guid+=n;
if((i==8)||(i==12)||(i==16)||(i==20))
guid+="-";
}
returnguid;
}
--=============================================
--Author: JBen
--Createdate:2012-06-05
--Description:生成唯一标识ID,公共存储过程,可设置在别的存储过程调用此存储过程传不同的前缀
--=============================================
ALTERPROCEDURE[dbo].[pro_CreateGuid]
@PrefixNVARCHAR(10),
@outputV_guidNVARCHAR(40)OUTPUT
AS
BEGIN
--SETNOCOUNTONaddedtopreventextraresultsetsfrom
--interferingwithSELECTstatements.
SETNOCOUNTON;
SET@outputV_guid=@Prefix+REPLACE(CAST(NEWID()ASVARCHAR(36)),"-","")
END相关文章