C#生成唯一值的方法匯總


一、在 .NET 中生成

1、直接用.NET Framework 提供的 Guid() 函數,此種方法使用非常廣泛。GUID(全局統一標識符)是指在一台機器上生成的數字,它保證對在同一時空中的任何兩台計算機都不會生成重復的 GUID 值(即保證所有機器都是唯一的)。關於GUID的介紹在此不作具體熬述,想深入了解可以自行查閱MSDN。代碼如下:

代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string _guid = GetGuid();
Console.WriteLine("唯一碼:{0}\t長度為:{1}\n去掉連接符:{2}", _guid, _guid.Length, _guid.Replace("-", ""));

string uniqueIdString = GuidTo16String();
Console.WriteLine("唯一碼:{0}\t長度為:{1}", uniqueIdString, uniqueIdString.Length);

long uniqueIdLong = GuidToLongID();
Console.WriteLine("唯一碼:{0}\t長度為:{1}", uniqueIdLong, uniqueIdLong.ToString().Length);

}

/// <summary>
/// 由連字符分隔的32位數字
/// </summary>
/// <returns></returns>
private static string GetGuid()
{
System.Guid guid = new Guid();
guid = Guid.NewGuid();
return guid.ToString();
}

/// <summary> 
/// 根據GUID獲取16位的唯一字符串 
/// </summary> 
/// <param name=\"guid\"></param> 
/// <returns></returns> 
public static string GuidTo16String()
{
long i = 1;
foreach (byte b in Guid.NewGuid().ToByteArray())
i *= ((int)b + 1);

return string.Format("{0:x}", i - DateTime.Now.Ticks);
}

/// <summary> 
/// 根據GUID獲取19位的唯一數字序列 
/// </summary> 
/// <returns></returns> 
public static long GuidToLongID()
{
byte[] buffer = Guid.NewGuid().ToByteArray();
return BitConverter.ToInt64(buffer, 0);
}

}
}

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

 代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string uniqueNum = GenerateOrderNumber();
Console.WriteLine("唯一碼:{0}\t 長度為:{1}", uniqueNum, uniqueNum.Length);

//測試是否會生成重復
Console.WriteLine("時間+RNGCryptoServiceProvider()結合生成的唯一值,如下:");
string _tempNum = string.Empty;
for (int i = 0; i < 1000; i++)
{
string uNum = GenerateOrderNumber();
Console.WriteLine(uNum);
if (string.Equals(uNum, _tempNum))
{
Console.WriteLine("上值存在重復,按Enter鍵繼續");
Console.ReadKey();
}

//Sleep當前線程,是為了延時,從而不產生重復值。可以把它注釋掉測試看
Thread.Sleep(300);

_tempNum = uNum;
}

}

/// <summary>
/// 唯一訂單號生成
/// </summary>
/// <returns></returns>
public static string GenerateOrderNumber()
{
string strDateTimeNumber = DateTime.Now.ToString("yyyyMMddHHmmssms");
string strRandomResult = NextRandom(1000, 1).ToString();

return strDateTimeNumber + strRandomResult;
}

/// <summary>
/// 參考:msdn上的RNGCryptoServiceProvider例子
/// </summary>
/// <param name="numSeeds"></param>
/// <param name="length"></param>
/// <returns></returns>
private static int NextRandom(int numSeeds, int length)
{
// Create a byte array to hold the random value. 
byte[] randomNumber = new byte[length];
// Create a new instance of the RNGCryptoServiceProvider. 
System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider();
// Fill the array with a random value. 
rng.GetBytes(randomNumber);
// Convert the byte to an uint value to make the modulus operation easier. 
uint randomResult = 0x0;
for (int i = 0; i < length; i++)
{
randomResult |= ((uint)randomNumber[i] << ((length - 1 - i) * 8));
}

return (int)(randomResult % numSeeds) + 1;
}
}
}

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

代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1

class Program
{
static void Main(string[] args)
{
string uniqueText = GenerateUniqueText(8);
Console.WriteLine("唯一碼:{0}\t 長度為:{1}", uniqueText, uniqueText.Length);

//測試是否會生成重復 
Console.WriteLine("由[0-9A-Z] + NewGuid() 結合生成的唯一值,如下:");
IList<string> list = new List<string>();
for (int i = 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>
/// <param name="num">特定位數</param>
/// <returns></returns>
public static string GenerateUniqueText(int num)
{
string randomResult = string.Empty;
string readyStr = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char[] rtn = new char[num];
Guid gid = Guid.NewGuid();
var ba = gid.ToByteArray();
for (var i = 0; i < num; i++)
{
rtn[i] = readyStr[((ba[i] + ba[num + i]) % 35)];
}

foreach (char r in rtn)
{
randomResult += r;
}

return randomResult;
}

}
}

4、用單例模式實現,由[0-9a-z]組合生成的唯一值,此文不討論單例模式的多種實現方式與性能問題,隨便弄一種方式實現,代碼如下:

Program.cs 程序:

代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Collections;
using System.Xml;

namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
CreateID createID = CreateID.GetInstance();

//測試是否會生成重復 
Console.WriteLine("單例模式實現,由[0-9a-z]組合生成的唯一值,如下:");
IList<string> list = new List<string>();
for (int i = 1; i <= 1000000000; i++)
{
string strUniqueNum = 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>
public class CreateID
{
private static CreateID _instance;
private static readonly object syncRoot = new object();
private EHashtable hashtable = new EHashtable();
private string _strXMLURL = string.Empty;

private CreateID()
{
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";

}

public static CreateID GetInstance()
{
if (_instance == null)
{
lock (syncRoot)
{
if (_instance == null)
{
_instance = new CreateID();
}
}
}

return _instance;
}

/// <summary>
/// 創建UniqueID
/// </summary>
/// <returns>UniqueID</returns>
public string CreateUniqueID()
{
long _uniqueid = GetGuidFromXml();

return Convert10To36(_uniqueid);
}

/// <summary>
/// 獲取UniqueID總記錄,即獲取得到的這個ID是第幾個ID
/// 更新UniqueID使用的個數,用於下次使用
/// </summary>
/// <returns></returns>
private long GetGuidFromXml()
{
long record = 0;
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(_strXMLURL);
XmlElement rootNode = xmldoc.DocumentElement;
//此次的個數值
record = Convert.ToInt64(rootNode["record"].InnerText);
//此次的個數值+1 == 下次的個數值
rootNode["record"].InnerText = Convert.ToString(record + 1);
xmldoc.Save(_strXMLURL);

return record;
}

/// <summary>
/// 10進制轉36進制
/// </summary>
/// <param name="intNum10">10進制數</param>
/// <returns></returns>
private string Convert10To36(long intNum10)
{
string strNum36 = string.Empty;
long result = intNum10 / 36;
long remain = 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;
}

return strNum36;
}

}

/// <summary>
/// Summary description for EHashTable
/// </summary>
public class EHashtable : Hashtable
{
private ArrayList list = new ArrayList();
public override void Add(object key, object value)
{
base.Add(key, value);
list.Add(key);
}
public override void Clear()
{
base.Clear();
list.Clear();
}
public override void Remove(object key)
{
base.Remove(key);
list.Remove(key);
}
public override ICollection Keys
{
get
{
return list;
}
}
}

}

XML:

代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<root>
<record id="record">1</record>
</root>

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

復制代碼 代碼如下:

function newGuid() { //方法一:
var guid = "";
var n = (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
for (var i = 1; i <= 8; i++) {
guid += n;
}
return guid;
}

function newGuid() { //方法二:
var guid = "";
for (var i = 1; i <= 32; i++) {
var n = Math.floor(Math.random() * 16.0).toString(16);
guid += n;
if ((i == 8) || (i == 12) || (i == 16) || (i == 20))
guid += "-";
}
return guid;
}

三、在SQL存儲過程生成GUID,代碼如下:

復制代碼 代碼如下:

-- =============================================
-- Author: wangws
-- Create date: 2015-06-05
-- Description: 生成唯一標識ID,公共存儲過程,可設置在別的存儲過程調用此存儲過程傳不同的前綴
-- =============================================
ALTER PROCEDURE [dbo].[pro_CreateGuid] 
@Prefix NVARCHAR(10),
@outputV_guid NVARCHAR(40) OUTPUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for procedure here
SET @outputV_guid = @Prefix + REPLACE(CAST(NEWID() AS VARCHAR(36)),'-','')
END


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM