Как получить 32-битный уникальный номер в Java? - PullRequest
2 голосов
/ 10 декабря 2010

Мне нужно сгенерировать уникальное число 32 бита в Java. Мне нужно вернуть номер как Java int, который требуется для интерфейса. Можете ли вы поделиться некоторыми идеями по этому поводу?

Номер будет использоваться как MySQL PK, и несколько потоков могут генерировать свои собственные уникальные идентификаторы одновременно. (Извините, мы решили не использовать инкрементный идентификатор MySQL)

Я пробовал класс 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);

Ответы [ 3 ]

5 голосов
/ 10 декабря 2010

Насколько "уникальны" вы хотите?Короче, что такое домен коллизий?Если вы имеете дело с тысячами ключей, то Random.nextInt () делает именно то, что вы хотите, относительно того, что вы пытались использовать с UUID версии 4 (UUID v4 генерирует 128 случайных битов).

Есливам нужно что-то с меньшей вероятностью столкновения, тогда вам нужно иметь глобально увеличенное целое число, но здесь нужно быть очень осторожным, например, поддерживать состояние между запусками JVM.Для этого вам следует заглянуть в AtomicIntegers .

0 голосов
/ 10 декабря 2010

Я думаю, вы можете использовать 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;

    }
0 голосов
/ 10 декабря 2010

Подход SecureRandom хорош, но не сажайте на него семя.Он выберет свое собственное начальное число (предположительно) безопасным способом.

Вы также можете использовать UUID и просто отбрасывать ненужные биты, например,

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

РЕДАКТИРОВАТЬ: ВыТакже следует помнить, что SecureRandom значительно медленнее, чем Random.Так как здесь вы не используете шифрование, почему бы не использовать Random?

...