zoukankan      html  css  js  c++  java
  • 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} 长度为:{1} 去掉连接符:{2}", _guid, _guid.Length, _guid.Replace("-", ""));

    string uniqueIdString = GuidTo16String();
    Console.WriteLine("唯一码:{0} 长度为:{1}", uniqueIdString, uniqueIdString.Length);

    long uniqueIdLong = GuidToLongID();
    Console.WriteLine("唯一码:{0} 长度为:{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} 长度为:{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} 长度为:{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} {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} {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

  • 相关阅读:
    spring Bean的完整生命周期
    idea+maven+ssm搭建boot_crm项目遇到的问题
    面试题:死锁的四个必要条件
    面试题:静态代理和动态代理的区别和联系 没用
    面试题: Struts2
    我所总结的设计模式 合应用场景
    hibernate 对象OID
    hibernate第三天 一对多 , 多对多
    hibernate里的实体类中不能重写toString
    存储前set方法相互关联 只关联了一方 分别set
  • 原文地址:https://www.cnblogs.com/Alex80/p/6893658.html
Copyright © 2011-2022 走看看