RandomStringUtils.randomAlphanumeric(30)是一个有效的GUID策略吗?

时间:2016-01-09 06:04:52

标签: java guid uuid distributed-computing primary-key-design

我需要一个随机字符串生成器,它会生成 字母数字 字符串,以用作 唯一 键在 30个字符或更少 的分布式系统中。它不能包含任何特殊字符。

RandomStringUtils#randomAlphanumeric会为此工作吗?

底层实现使用java.util.Random

唯一密钥集可能不到1000亿,系统每秒最多可处理1000条记录。

如何证明此策略具有足够低的冲突概率作为主键生成器?

3 个答案:

答案 0 :(得分:3)

java.util.Random实现了一个LCG算法,其周期为2 ^ 48个数字,因此RandomStringUtils将与此实现一样好,并且1000亿个30个字符的字符串将需要~1%的2 ^ 48个随机元素。

请注意,java.util.Random不具有加密安全性,因此给定一些GUID可以推断出下一个GUID,因此我使用另一个使用加密安全随机数生成器的实现(例如java.util) .SecureRandom)。

答案 1 :(得分:1)

为什么你不想使用java.util.UUID课程?它返回32位字符String的随机UUID。 示例实现:

import java.util.UUID;

public class GenerateUUID {

   public static final void main(String... aArgs){
     //generate random UUIDs
     UUID idOne = UUID.randomUUID();
     UUID idTwo = UUID.randomUUID();
     log("UUID One: " + idOne);
     log("UUID Two: " + idTwo);
   }

   private static void log(Object aObject){
     System.out.println(String.valueOf(aObject));
   }
} 

答案 2 :(得分:0)

随机性不是唯一的。使用随机数生成获取“唯一”值会遇到生日问题https://en.wikipedia.org/wiki/Birthday_attack。这会将2 ^ 48中的1概率转换为2 ^ 24中的1概率,您击中目标的速度将比您想象的要快。使用UUID;它们的设计具有普遍的独特性。

32个字符:

UUID.randomUUID().toString.replace("-","")

22个字符:

UUID uuid = UUID.randomUUID();
String uuidStr = Base64.encodeBase64URLSafeString(ByteBuffer.wrap(new byte[16])
    .putLong(uuid.getMostSignificantBits())
    .putLong(uuid.getLeastSignificantBits())
            .array()).replace("=", "");