请选择 进入手机版 | 继续访问电脑版

无忧编程_ASP.NET  / C# / PHP 程序员的软件世界

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1923|回复: 0

如何无损耗的压缩GUID为12位?方法介绍

[复制链接]

399

主题

432

帖子

1791

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1791
发表于 2019-1-11 15:00:30 | 显示全部楼层 |阅读模式
如何无损耗的压缩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位的方法呢?
如果你有更好的做法,可以共享出来。

附源代码

[C#] 纯文本查看 复制代码
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();
            }

参考资料:https://www.cnblogs.com/iamsunri ... /07/14/2106473.html
windows .net(C#+MSSQL) linux(php+mysql)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|软件编程 ( 鄂ICP备11006601号鄂公网安备 42011102001337号 |

GMT+8, 2019-3-21 00:25 , Processed in 0.137596 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表