我需要在Java中生成一个唯一的32位数。我需要将数字作为Java int返回,这是接口所需的。你能否就此分享一些想法?
该号码将用作MySQL PK,并且多个线程可以同时生成自己的唯一ID。 (抱歉,决定不使用MySQL增量ID)
我尝试了UUID类,但它生成的数据似乎比我可以使用的位数多。
我发现了这个,但不确定它是否有效:
// seems no way to get int
UUID id = UUID.randomUUID();
System.out.println(id);
// not working either?
java.rmi.server.UID uid = new java.rmi.server.UID();
System.out.println(uid.toString());
// the one i am using
SecureRandom prng = SecureRandom.getInstance("SHA1PRNG");
prng.setSeed(System.currentTimeMillis());
int ret = prng.nextInt();
System.out.println(ret);
答案 0 :(得分:5)
你想要“独特”吗?简而言之,碰撞域是什么?如果您正在处理成千上万的密钥,那么Random.nextInt()完全符合您对第4版UUID所尝试的内容(UUID v4生成128个随机位)。
如果你需要一个碰撞机会较少的东西,那么你需要有一个全局递增的整数,但这里需要注意的是诸如在JVM启动之间保持状态。为此,您应该查看AtomicIntegers。
答案 1 :(得分:0)
SecureRandom
方法很好,但不要在其上设置种子。它会以(可能)安全的方式选择它自己的种子。
你也可以使用UUID,只丢弃你不需要的位,例如
int key = (int)UUID.randomUUID().getLeastSignificantBits();
编辑:您还应该知道SecureRandom
明显慢于Random
。既然你没有在这里加密,为什么不使用Random
?
答案 2 :(得分:0)
我认为你可以使用32位哈希函数。 详细信息在以下教程中给出 http://www.concentric.net/~ttwang/tech/inthash.htm
private static int hash(int key){
key = ~key + (key << 15); // key = (key << 15) - key - 1;
key = key ^ (key >>> 12);
key = key + (key << 2);
key = key ^ (key >>> 4);
key = key * 2057; // key = (key + (key << 3)) + (key << 11);
key = key ^ (key >>> 16);
return key;
}