随笔 - 317, 文章 - 0, 评论 - 453, 阅读 - 114万
  博客园  :: 首页  :: 新随笔  :: 订阅 订阅  :: 管理

使用36进制,无损压缩GUID到26位

Posted on   PHP-张工  阅读(3037)  评论(5编辑  收藏  举报

MSDN的解释:

GUID 是一个 128 位整数(16 字节),可用于所有需要唯一标识符的计算机和网络。此标识符重复的可能性非常小。

UInt64 表示 64 位无符号整数。值类型表示值介于 0 到 18,446,744,073,709,551,615 之间的无符号整数。

原理将GUID拆分成两个 64位的Uint64,再将UInt64转换为36进制字符形式。

UInt64最大值转换成36进制为13位。所以生成的字符长度为26位。

转换代码如下:

/// <summary>
/// Convert36 的摘要说明
/// </summary>
public class Convert36
{
    public Convert36()
    {
        //
        // TODO: 在此处添加构造函数逻辑
        //
    }
 
    private const string BASE_CHAR = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
    //转换为段字符
    private static string GetLongNo(UInt64 num, int length)
    {
        string str = "";
        while (num > 0)
        {
            int cur = (int)(num % 36);
            str = BASE_CHAR[cur] + str;
            num = num / 36;
        }
        if (str.Length > length)
        {
            str = str.Substring(str.Length - length);
        }
        else
        {
            str = str.PadLeft(length, '0');
        }
 
        return str;
    }
 
    //解析段字符
    private static UInt64 GetLongNum(string strNo)
    {
        UInt64 num = 0;
        for (int i = 0; i < strNo.Length; i++)
        {
            num += (UInt64)BASE_CHAR.IndexOf(strNo[i]) * (UInt64)Math.Pow(BASE_CHAR.Length, strNo.Length - i - 1);
        }
 
        return num;
    }
 
    /// <summary>
    /// 压缩GUID
    /// </summary>
    /// <param name="g"></param>
    /// <returns></returns>
    public static string GetGuidNo(Guid g)
    {
        string s = g.ToString().Replace("-", "").ToUpper();
        string s1 = s.Substring(0, 16);
        string s2 = s.Substring(16);
        UInt64 l1 = UInt64.Parse(s1, System.Globalization.NumberStyles.HexNumber);
        UInt64 l2 = UInt64.Parse(s2, System.Globalization.NumberStyles.HexNumber);
        string str1 = GetLongNo(l1, 13);
        string str2 = GetLongNo(l2, 13);
 
        return str1 + str2;
    }
 
    /// <summary>
    /// 获取GUID
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static Guid GetGuid(string str)
    {
        if (str.Length != 26)
        {
            throw new Exception("字符串错误!长度必须是26位!");
        }
        string s1 = str.Substring(0, 13);
        string s2 = str.Substring(13);
        UInt64 l1 = GetLongNum(s1);
        UInt64 l2 = GetLongNum(s2);
        string str1 = l1.ToString("X");
        string str2 = l2.ToString("X");
        string strGuid = str1.PadLeft(16, '0');
        strGuid += str2.PadLeft(16, '0');
        Guid g = new Guid(strGuid);
        return g;
    }
}

实例下载:https://files.cnblogs.com/zjfree/Convert36.rar

 

2024-03-25,使用 [0~9][a~z][A~Z] 转换为62进制,长度最长为22位,代码如下:

复制代码
public static string GuidShort()
{
    var bytes = Guid.NewGuid().ToByteArray();
    //bytes = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, };
    //bytes = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
    var v1 = BitConverter.ToUInt64(bytes, 0);
    var v2 = BitConverter.ToUInt64(bytes, 8);

    string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    UInt64 len = (UInt64)str.Length;

    StringBuilder s1 = new StringBuilder();
    StringBuilder s2 = new StringBuilder();

    for (int i = 0; i<11; i++)
    {
        s1.Insert(0, str[(int)(v1 % len)]);
        v1 = v1 / len;
        s2.Insert(0, str[(int)(v2 % len)]);
        v2 = v2 / len;
    }

    var strReult = s1.ToString() + s2.ToString();

    return strReult;
}
复制代码

 

努力加载评论中...
点击右上角即可分享
微信分享提示