java - 极其紧凑的 UUID(使用所有字母数字字符)

标签 java math

我需要一个非常紧凑的 UUID,越短越好。
为此,我写道:

    public String getBase36UIID() {
        // More compact version of UUID
        String strUUID = UUID.randomUUID().toString().replace("-", "");
        return new BigInteger(strUUID, 16).toString(36);
    }
通过执行此代码,我得到,例如:
5luppaye6086d5wp4fqyz57xb
这很好,但不是最好的。 Base 36 使用所有数字和小写字母,但不使用大写字母。
如果可以使用大写字母作为与小写字母分开的数字,则有可能将数字基数 62 理论化,由这些数字组成:
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
我还可以使用重音字符(例如“è”或“é”)或特殊字符(例如“$”或“!”)来理论化数字基数,从而进一步增加可用数字的数量。
然而,使用这些重音或特殊字符可能会给我带来问题,所以目前我不想考虑它们。
在所有这些前提之后,我怎样才能将代表我的 UUID 的 BigInteger 转换为上面理论化的基数 62,以使其更加紧凑?谢谢
我已经验证过像下面这样的代码不可用,因为每个超过 36 的基数都被视为基数 10:
return new BigInteger(strUUID, 16).toString(62);
毕竟,在数学中没有我想象的基数 62,但我想在 Java 中可以创建它。

最佳答案

将数字转换为任意基数的通用算法基于除以余数。
您首先将数字除以基数。余数为您提供数字的最后一位 - 您将其映射到一个符号。如果商不为零,则将其除以底数。余数为您提供倒数第二个数字。然后你用商重复这个过程。
在 Java 中,使用 BigInteger:

String toBase62(BigInteger number) {
    String symbols = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    BigInteger base = BigInteger.valueOf(symbols.length());

    StringBuilder result = new StringBuilder();
    do {
        BigInteger[] quotientAndRemainder = number.divideAndRemainder(base);
        number = quotientAndRemainder[0];
        result.append(symbols.charAt(quotientAndRemainder[1].intValue()));
    } while (number.compareTo(BigInteger.ZERO) > 0);
    
    return result.reverse().toString();
}
你需要标识符是 UUID 吗?难道它不能只是任何随机的字母和数字序列吗?如果这是可以接受的,您就不必处理基于数字的转换。
String randomString(int length) {
    String symbols = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    Random rnd = new Random();
    StringBuilder str = new StringBuilder();
    for (int i = 0; i < length; i++) {
        str.append(symbols.charAt(rnd.nextInt(symbols.length())));
    }
    return str.toString();
}

关于java - 极其紧凑的 UUID(使用所有字母数字字符),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63457605/

相关文章:

java - 您可以定义抽象类的子类而不定义父类(super class)中定义的任何抽象方法吗?为什么?

math - 计算二维空间中两点之间的距离?

c++ - 如何渲染一个顶点尽可能少的圆?

java - 我如何使用java获取BIOS信息?

math - 给定三角形顶点的坐标,求 3D 三角形面的法线角

algorithm - [1+2a+3a^2+4a^3+....+ba^(b-1)] MOD M 是否有 O(logn) 解

javascript - 顺时针循环一组数字

java - JXTreeTable 模型不允许使用 insertNodeInto()

java - Spring Boot Jackson ResponseEntity 找不到类的序列化器

java - PHP 中使用 Java 进行 SHA-256 盐验证