C#生成唯一值的方法汇总
C#生成唯一值的方法汇总
发布时间:2016-12-28 来源:查字典编辑
摘要:生成唯一值的方法很多,下面就不同环境下生成的唯一标识方法一一介绍,作为工作中的一次总结,有兴趣的可以自行测试:一、在.NET中生成1、直接用...

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

一、在 .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]组合生成的唯一值,此文不讨论单例模式的多种实现方式与性能问题,随便弄一种方式实现,代码如下:

Demo结构如图:

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

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(@"....") + "XMLsrecord.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: JBen

-- Create date: 2012-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

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新C#教程学习
热门C#教程学习
编程开发子分类