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

Demo结构如图:

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:      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

(0)

相关推荐

  • C#生成指定范围内的不重复随机数

    C#生成指定范围内的不重复随机数 // Number随机数个数 // minNum随机数下限 // maxNum随机数上限 public int[] GetRandomArray(int Number,int minNum,int maxNum) { int j; int[] b=new int[Number]; Random r=new Random(); for(j=0;j<Number;j++) { int i=r.Next(minNum,maxNum+1); int num=0; for

  • C#生成唯一不重复订单号

    在弄电商类网站的时候,往往是根据年月日时分秒的格式生成订单号(yyyyMMddHHmmss),为了解决并发性,就直接在生成订单号的区域块加上lock. 下面,我们来简单测试一下. 1.新建项目(控制台应用程序) 2.新建一个类:OrderIdHelper.cs /// <summary> /// 订单助手 /// </summary> class OrderIdHelper { private static readonly object Locker = new object()

  • C#实现随机数产生类实例

    本文实例讲述了C#实现随机数产生类.分享给大家供大家参考.具体分析如下: 这个类主要扩展的random的使用,对一个经常需要使用的随机数生成进行了封装,可以产生指定范围内的随机数,可以随机生成字符串等 using System; namespace DotNet.Utilities { /// <summary> /// BaseRandom /// 产生随机数 /// /// 随机数管理,最大值.最小值可以自己进行设定. /// </summary> public class B

  • C#随机设置900-1100毫秒延迟的方法

    本文实例讲述了C#随机设置900-1100毫秒延迟的方法.分享给大家供大家参考.具体如下: using System; using System.Threading; ///<summary> /// A time delay of 900..1100 milliseconds ///</summary> namespace RobvanderWoude { class WaitASecond { static void Main( string[] args ) { // Cho

  • C#利用时间和随即字符串创建唯一的订单编号

    使用RNGCryptoServiceProvider类创建唯一的最多8位数字符串,再在前面拼接上年月日时分秒产生的字符串,最大限度的保证生成的字符串是唯一的. 大家也可以根据自己的需求修改,日期可以取值到毫秒,这样更能保证生成的字符串是唯一的. private static string GetUniqueKey() { int maxSize = 8; int minSize = 5; char[] chars = new char[62]; string a; a = "abcdefghij

  • C#生成随机数的方法小结

    本文实例总结了C#生成随机数的方法.分享给大家供大家参考.具体分析如下: 开始,很简单地使用System.Random类来生成随机数.很快,问题就来了,发现当random的生成间隔小于1ms时,随机数就重复了(仅限于每次都新建Random对象),因为新建random时候是默认以当前时间作为随机种子的.将random改为单例,重复数的几率小了,但是随机数在一段时间后循环了(伪随机数嘛,没办法,要求不了这么多的). 所以,特意在网上找了一些资料,并亲自作了一些性能比较,在此作些总结. System.

  • c#唯一值渲染实例代码

    该着色方法一句着色图层中要素类的某个数值字段的属性值,按这个属性值为每种不同值得要素单独分配一种显示符号样式.关键在于获取该字段所有要素的唯一值(即将所有在该字段中属性值相同的要素归为一种),利用UniqueValueRenderer的AddValue方法即可进行渲染 需要添加的类库 复制代码 代码如下: using System.Collections;using System.Windows.Forms;using ESRI.ArcGIS.Display;using ESRI.ArcGIS.

  • C#利用Random得随机数求均值、方差、正态分布的方法

    本文实例讲述了C#利用Random得随机数求均值.方差.正态分布的方法.分享给大家供大家参考.具体如下: 最近在做中小学试卷分析系统,其中数据的分析让自己很头疼,整个系统采用B/S架构.在分析试卷难度梯度的时候需要用到正态分布,自己做了一些,也查阅了一些资料,终于掌握了将一组数据分析检验,最后生成正态分布. (1)利用随机函数rand()生成(0,1)区间的100个均匀分布随机数: (2)计算这100个均匀分布随机数的均值和方差, (3)将这100个均匀分布的随机数,及其均值和方差保存到文本文件

  • C# 生成随机数的代码

    /// 构造随机数 种子 static int GetRandomSeed() { byte[] bytes = new byte[4]; System.Security.Cryptography.RNGCryptoServiceProvider rng = new System.Security.Cryptography.RNGCryptoServiceProvider(); rng.GetBytes(bytes); return BitConverter.ToInt32(bytes, 0);

  • C#生成不重复随机字符串类

    本文实例讲述了C#生成不重复随机字符串类.分享给大家供大家参考.具体如下: 这个C#类用于随机产生不重复的字符串,可以指定字符串范围,可以指定要产生字符串的长度 using System; namespace DotNet.Utilities { public class RandomOperate { // 一:随机生成不重复数字字符串 private int rep = 0; public string GenerateCheckCodeNum(int codeCount) { string

随机推荐