简体   繁体   English

如何在Java中获得32位唯一数字?

[英]How to get 32 bits unique number in Java?

I need to generate an unique number of 32 bits in Java. 我需要在Java中生成唯一的32位数字。 I need to return the number as Java int, which is required by the interface. 我需要将数字返回为Java int,这是接口所必需的。 Can you please share some ideas on this? 能否请您分享一些想法?

The number will be used as MySQL PK and several threads could be generating their own unique id at same time. 该数字将用作MySQL PK,并且多个线程可以同时生成自己的唯一ID。 (Sorry it is decided not to use MySQL incremental id) (很抱歉,决定不使用MySQL增量ID)

I tried UUID class but it seems the data it generates has more bits than I can use. 我尝试了UUID类,但似乎它生成的数据具有比我可以使用的更多的位。

I found this but not sure if it works: 我发现了这一点,但不确定是否可行:

    // 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);

How "unique" are you wanting? 您要有多“独特”? In short, what is the collision domain? 简而言之,冲突域是什么? If you are dealing with thousands of keys then Random.nextInt() does exactly what you want relative to what you tried with version 4 UUIDs (UUID v4 generates 128 random bits). 如果要处理成千上万个键,则Random.nextInt()会相对于您尝试使用版本4 UUID(UUID v4生成128个随机位)进行准确的操作。

If you need something with a less chance of collision then you need to have a globally incremented integer but there is much care to be taken here such as keeping state between JVM startups. 如果您需要发生冲突的可能性较小的东西,则需要具有一个全局递增的整数,但是这里要多加注意,例如保持JVM启动之间的状态。 For that you should look into AtomicIntegers . 为此,您应该查看AtomicIntegers

The SecureRandom approach is fine, but don't set the seed on it. SecureRandom方法很好,但不要在上面设置种子。 It will choose it's own seed in a (presumably) secure manner. 它将以(大概)安全的方式选择自己的种子。

You could also use a UUID and just discard the bits you don't need, eg 您也可以使用UUID并丢弃不需要的位,例如

int key = (int)UUID.randomUUID().getLeastSignificantBits();

EDIT: You should also be aware that the SecureRandom is significantly slower than Random . 编辑:您还应该知道, SecureRandom的速度明显比Random慢。 Since you're not doing crypto here, why not use Random ? 由于您不在这里进行加密,为什么不使用Random

I think you can use a 32-bit hash function. 我认为您可以使用32位哈希函数。 details are given in the following tutorial http://www.concentric.net/~ttwang/tech/inthash.htm 详细信息在以下教程中提供: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;

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM