欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-02-22 11:04:22
生成唯一值的方法很多,下面就不同环境下生成的唯一标识方法一一介绍,作为工作中的一次总结,有兴趣的可以自行测试: 一、在 .net 中生成 1、直接用.net frame...

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

一、在 .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#生成唯一值的方法汇总

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