GUID 字符串,16位字符串,19位數字


在C#中生成唯一的字符串和數字

      當我們想要獲得一個唯一的key的時候,通常會想到GUID。這個key非常的長,雖然我們在很多情況下這並不是個問題。但是當我們需要將這個36個字符的字符串放在URL中時,會使的URL非常的丑陋。

      想要縮短GUID的長度而不犧牲它的唯一性是不可能的,但是如果我們能夠接受一個16位的字符串的話是可以做出這個犧牲的。

      我們可以將一個標准的GUID 21726045-e8f7-4b09-abd8-4bcc926e9e28  轉換成短的字符串 3c4ebc5f5f2c4edc

      下面的方法會生成一個短的字符串,並且這個字符串是唯一的。重復1億次都不會出現重復的,它也是依照GUID的唯一性來生成這個字符串的。

        private string GenerateStringID()
        {
            long i = 1;
            foreach (byte b in Guid.NewGuid().ToByteArray())
            {
                i *= ((int)b + 1);
            }
            return string.Format("{0:x}", i - DateTime.Now.Ticks);
        }

      如果你想生成一個數字序列而不是字符串,你將會獲得一個19位長的序列。下面的方法會把GUID轉換為Int64的數字序列。

        private long GenerateIntID()
        {
            byte[] buffer = Guid.NewGuid().ToByteArray();
            return BitConverter.ToInt64(buffer, 0);
        }

1)假設數據庫是這個樣子的:

 

2)運行以下控制台代碼:

static void Main(string[] args)
        {
            //測試bigint的讀取:
            using (SqlConnection con = new SqlConnection(@"server=.\sqlexpress;database=MyTest;integrated security=true"))
            {
                SqlCommand cmd = new SqlCommand("select top 1 number from tb_dbo", con);
                con.Open();
                IDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection | CommandBehavior.SingleRow);
                dr.Read();
                long n = Convert.ToInt64(dr["number"]);
                Console.WriteLine(n);
                dr.Close();
            }
        }

 

3)結果如下:

 

 

是否可以無損耗的壓縮GUID為12位呢?

當我們想要獲得一個唯一的key的時候,通常會想到GUID。這個key的長度是36位,如果將這個36為的字符串存儲或是用url傳遞的時候就會感覺非常的難看。
就算去掉-分隔符也有32位,如 EAA82B2DA9EA4E5B95330BAF9944FB35,如果轉為數字序列 如將guid轉為int64數字序列,長度也會有19位。
byte[] buffer = Guid.NewGuid().ToByteArray();  
long long_guid=BitConverter.ToInt64(buffer, 0);
這樣就會得到一個類似於  5472976187161141196 的19位長度的 數字序列。
如果我們將 5472976187161141196 分解為 54 72 97 61 87 161 141 196,應該可以用8個字符就可以顯示,但會有一部分是不可顯示的字符。
如果將這8個字符轉為base64,發現只需要10-14個為就能顯示完畢,將一些url用到的某些符號剔除,通常會產生12位的編碼較多,10位的編碼較少。
經過100萬次的測試,沒有發現會有重復的字符產生,不知道是否是完美的將guid 壓縮為12位的方法呢?
如果你有更好的做法,可以共享出來。
附源代碼
  public   static   string  UUID()
        {
            
byte [] buffer  =  Guid.NewGuid().ToByteArray();  
            
long  long_guid = BitConverter.ToInt64(buffer,  0 );

            
string  _Value  =  System.Math.Abs(long_guid).ToString();

            
byte [] buf = new   byte [_Value.Length];
            
int  p = 0 ;
            
for  ( int  i  =   0 ; i  <  _Value.Length;)
            {
                
byte  ph = System.Convert.ToByte(_Value[i]);

                
int  fix = 1 ;
                
if  ((i + 1 ) < _Value.Length)
                {
                    
byte  pl = System.Convert.ToByte(_Value[i + 1 ]);
                    buf[p]
= ( byte )((ph << 4 ) + pl);
                    fix
= 2 ;
                }
else {
                    buf[p]
= ( byte )(ph);
                }

                
if  ((i + 3 ) < _Value.Length)
                {
                    
if  (System.Convert.ToInt16(_Value.Substring(i, 3 )) < 256 )
                    {
                        buf[p]
= System.Convert.ToByte(_Value.Substring(i, 3 ));
                        fix
= 3 ;
                    }
                }
                p
++ ;
                i
= i + fix;
            }
            
byte [] buf2 = new   byte [p];
            
for  ( int  i = 0 ;i < p;i ++ )
            {
                buf2[i]
= buf[i];
            }
            
string  cRtn = System.Convert.ToBase64String(buf2);
            
if  (cRtn == null )
            {
                cRtn
= "" ;
            }
            cRtn
= cRtn.ToLower();
            cRtn
= cRtn.Replace( " / " , "" );
            cRtn
= cRtn.Replace( " + " , "" );
            cRtn
= cRtn.Replace( " = " , "" );
            
if  (cRtn.Length == 12
            {
                
return  cRtn;
            }
else {
               
return  UUID();
            }
        }

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM