在Java中的随机标识符

5
我希望能够在Java中生成随机标识符。该标识符应具有固定大小,并且生成相同标识符的概率应非常低(系统中约有500,000个用户)。此外,标识符应足够长,以致于无法通过暴力攻击“猜测”它。
到目前为止,我的方法大致如下:
String alphabet = "0123456789ABCDE....and so on";
int lengthOfAlphabet = 42; 
long length = 12; 

public String generateIdentifier(){
    String identifier = "";
    Random random = new Random(); 
    for(int i = 0;i<length;i++){
        identifier+= alphabet.charAt(random.nextInt(lengthOfAlphabet));
    }
    return identifier; 
}

我会在数据库中的约束条件中强制唯一性。如果我遇到已经创建的标识符,我就会继续生成,直到找到一个未被使用的为止。
我的假设是,我可以调整字母表长度和长度来获得我正在寻找的属性:
1. 碰撞很少发生; 2. 无法通过暴力破解获取; 3. 标识符应尽可能短,因为系统的用户必须输入它。
这种方法好吗?有没有人对“长度”的价值有什么想法?

13
在我们开始之前,请说明UUID.randomUUID()有什么问题?它是否太长了?它可以转换为更短的内容,例如在base 64中编码。 - Marko Topolnik
真正的随机数是通过量子涨落产生的,可以在以下网址生成:http://150.203.48.55/index.php - NimChimpsky
@Marko:我猜问题在于需求#3。有一些更容易输入的随机标识符(但这可能只是格式化/解析的问题)。 - Joachim Sauer
将用户的短字符串与存储在数据库中的散列值组合。用户只需要知道被散列的短字符串,并将其与存储的值进行比较。 - Averroes
除了将完整的128位表示为base-64数字之外,您还可以删除其中的一些部分,或者例如将两个半部分进行XOR运算。我认为这将保持唯一性和随机性,并将长度缩短。 - Marko Topolnik
显示剩余6条评论
2个回答

2

1
我建议保持简单,使用内置方法来表示编码为字符串的普通伪随机整数:
Random random = new Random(); 

/**
 * Generates random Strings of 1 to 6 characters. 0 to zik0zj
 */
public String generateShortIdentifier() {
    int number;
    while((number=random.nextInt())<0);
    return Integer.toString(number, Character.MAX_RADIX);
}

/**
 * Generates random Strings of 1 to 13 characters. 0 to 1y2p0ij32e8e7
 */
public String generateLongIdentifier() {
    long number;
    while((number=random.nextLong())<0);
    return Long.toString(number, Character.MAX_RADIX);
}

Character.MAX_RADIX 是36,它等于由0到9和A到Z组成的字母表。简而言之,您将把随机整数转换为36进制数。

如果需要,您可以调整所需长度,但只要使用13个字符就可以编码2 ^ 63个数字。

编辑:修改后仅生成0到2 ^ 63,不含负数,但这取决于您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接