是否可以无损耗的压缩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();
}
{
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();
}
}