生成短的8位UUID(C#+JAVA)

方案一:

本算法首先随机生成一个32位字符的UUID;接着,由于UUID都为十六进制,所以将UUID分成8组,每4个为一组;然后,通过分别将他们进行模91操作,通过模运算的结果,去字典数组中索引得到相应的字符。

而字典数组,则是62+29个可打印字符,大小写字母、数字、不包括单双引号的符号,相比网上能找到62个字符的版本,进一步降低了重复概率。

经测试,62个字符的方案在我这里测试的时候,生成三百万条数据时出现了一个重复;目前我正在测试91个字符的方案,准备生成10个小目标的数据量,看看会不会发生重复。

网上都是JAVA版,这里按语法简单调整成C#的版本,代码贴出来供大家参考。

//***************************

//测试结果:

//62个字符时,一百多万的时候就已经有一个重复项了,不过直到1个小目标也没再出现第二个重复项;

//91个字符时,直到1个小目标的量,一直没有出现重复项。

//结论:短UUID在一定业务场景下可以用,但其重复的可能性依然存在,所以要给字段加聚集索引,且判断Insert是否失败,若失败则重新生成一个,理论上不可能失败3次。

//***************************

C#版:

        public static String[] chars = new String[] { "a", "b", "c", "d", "e", "f", // 6
             "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",  // 13
             "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",  // 13
             "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",  // 13
             "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",  // 13
             "W", "X", "Y", "Z",
             "!", "#", "$", "%", "&", "(", ")", "*", "+", ",", "-", ".", "/",   // 13
              ":", ";", "<", "=", ">", "?", "@", "[", @"\", "]", "^", "_", "{", // 13
             "|", "}", "~"};                                                    // 3

        /// <summary>
        /// 生成8位的短UUID
        /// </summary>
        public string ShortUuid()
        {
            StringBuilder shortBuffer = new StringBuilder();

            // 生成32位UUID
            var uuidN = Guid.NewGuid().ToString("N");  
            for (int i = 0; i < 8; i++)
            {
                // 4个一组
                string strSub = uuidN.Substring(i * 4, 4);
                int x = Int32.Parse(strSub, System.Globalization.NumberStyles.HexNumber);

                // 模91(62+29=91=0x5B),取chars[]对应的字符
                string strTmp = chars[x % 0x5B];  // 风险点
                shortBuffer.Append(strTmp);
            }
            return shortBuffer.ToString();
        }

JAVA版:

// 62+29个字符
public static String[] chars = new String[] { "a", "b", "c", "d", "e", "f",
  "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
  "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
  "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
  "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
  "W", "X", "Y", "Z",
  "!", "#", "$", "%", "&", "(", ")", "*", "+", ",", "-", ".", "/",   // 13
  ":", ";", "<", "=", ">", "?", "@", "[", "\\", "]", "^", "_", "{",  // 13
  "|", "}", "~"};                                                    // 3

public static String generateShortUuid() {
  StringBuffer shortBuffer = new StringBuffer();
  // 生成32位UUID
  String uuid = UUID.randomUUID().toString().replace("-", "");

  for (int i = 0; i < 8; i++) {
    // 4个一组
    String str = uuid.substring(i * 4, i * 4 + 4);
    int x = Integer.parseInt(str, 16);

    // 模91(62+29=91=0x5B),取chars[]对应的字符
    shortBuffer.append(chars[x % 0x5B]);
  }
  return shortBuffer.toString(); 
}

// ************************** 可爱的分隔线 **************************

方案二:

上面的代码还是重复的可能性,还是这个靠谱绝对不重复,虽然最大长度达22位:

//JAVA

private String generateShortUuid(String uuidString)
{
        //UUID uuid1 = UUID.randomUUID();
        UUID uuid1 = UUID.fromString(uuidString);

        ByteBuffer byteBuffer1 = ByteBuffer.wrap(new byte[16]);
        byteBuffer1.putLong(uuid1.getMostSignificantBits());
        byteBuffer1.putLong(uuid1.getLeastSignificantBits());

        String base64String1 = Base64.getEncoder().encodeToString(byteBuffer1.array());
        // 删除尾部的"=="
        base64String1 = base64String1.substring(0, base64String1.length() - 2);
        return base64String1;

}
// C#就只有一行
Convert.ToBase64String(Guid.NewGuid().ToByteArray()).TrimEnd('=');

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值