1. 程式人生 > >C#生成唯一值的方法彙總

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

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、用日期 用 DateTime.Now.ToString("yyyyMMddHHmmssms") + Guid.NewGuid()作種子生成隨機數組合生成唯一值,程式碼如下:

/// <summary>
        /// 生成訂單編碼,20位,日期部分在二次隨機數
        /// </summary>
        /// <returns></returns>
        public static string CreateOrderNo()
        {
            var strNo = DateTime.Now.ToString("yyMMddHHmmssms");
                var iSeed = CreateRandSeed();
                var iSeed2 = NextRandom(1000, 2);
                iSeed = iSeed - 500 + iSeed2;
                var rnd = new Random(iSeed);
                var strExt = rnd.Next(1000, 10000);
                strNo += strExt;

                //再拼接2位
                rnd = new Random(iSeed - 1);
                strExt = rnd.Next(10, 99);
                strNo += strExt;
                return strNo;
        }
        /// <summary>  
        /// 參考:msdn上的RNGCryptoServiceProvider例子  
        /// </summary>  
        /// <param name="numSeeds"></param>  
        /// <param name="length"></param>  
        /// <returns></returns>  
        public 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;
        }  
        public static int CreateRandSeed()
        {
            var iSeed = 0;
            var guid = Guid.NewGuid().ToString();
            iSeed = guid.GetHashCode();
            return iSeed;
        } 



二、在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

--- end ---