12用Java生成数字唯一随机数

我正在开发一个应用程序,我们需要生成一些唯一的数字,实际上没有预定义的限制所以使用java UUD生成器并且工作正常。 现在我们给出了生成12位唯一随机数的新要求。

任何人都可以指出一些好的方法/算法来实现这一点,因为我在UUID生成的数字中看不到任何可能性。

提前致谢

通过调用random.nextInt生成每个数字。 为了保持唯一性,您可以通过将它们保存在一个集合中并检查该集合是否包含您每次生成的数字来跟踪到目前为止使用的随机数。

 public static long generateRandom(int length) { Random random = new Random(); char[] digits = new char[length]; digits[0] = (char) (random.nextInt(9) + '1'); for (int i = 1; i < length; i++) { digits[i] = (char) (random.nextInt(10) + '0'); } return Long.parseLong(new String(digits)); } 
 (long)Math.random()*1000000000000L 

但是有可能发生碰撞

为什么不使用序列? 从100,000,000,000到999,999,999,999? 记录上次生成的号码。


编辑:感谢奥拉 ,我修复了一个令人毛骨悚然的错误

使用StringBuilder()改进了检查的解决方案:

 public static long generateRandom() { Random random = new Random(); StringBuilder sb = new StringBuilder(); // first not 0 digit sb.append(random.nextInt(9) + 1); // rest of 11 digits for (int i = 0; i < 11; i++) { sb.append(random.nextInt(10)); } return Long.valueOf(sb.toString()).longValue(); } 
 Random random = new Random(); Math.round(random.nextFloat() * Math.pow(10,12)) 

我最近有一个非常相似的要求,想出了这个:

 import com.google.inject.Provider; import java.security.SecureRandom; import org.apache.commons.codec.binary.Base64; public final class SecureKeyProvider { private final SecureRandom rng; private final int entropyBytes; public SecureKeyProvider(int entropyBytes) { this.rng = new SecureRandom(); this.entropyBytes = entropyBytes; } public String get() { /* SecureRandom documentation does not state if it's thread-safe, * therefore we do our own synchronization. see * * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6498354 */ synchronized (this.rng) { final byte[] random = new byte[this.entropyBytes]; rng.nextBytes(random); return Base64.encodeBase64URLSafeString(random); } } } 

它使用我在项目中使用的apache commons的Base64编码器。 也许你想用简单的东西取而代之,但除此之外它还可以完成任务。

你可以尝试这样。这是生成12位数的随机数。你必须提到范围。

  package test; import java.util.Random; /** Generate random integers in a certain range. */ public final class RandomRange { public static final void main(String... aArgs){ log("Generating random integers in the range 100000000000..999999999999."); long START = 100000000000l; long END = 999999999999l; Random random = new Random(); for (int idx = 1; idx <= 10; ++idx){ showRandomInteger(START, END, random); } log("Done."); } private static void showRandomInteger(long aStart, long aEnd, Random aRandom){ if ( aStart > aEnd ) { throw new IllegalArgumentException("Start cannot exceed End."); } //get the range, casting to long to avoid overflow problems long range = (long)aEnd - (long)aStart + 1; // compute a fraction of the range, 0 <= frac < range long randomNumber = (long)(range * aRandom.nextDouble()); System.out.println(" fraction... "+randomNumber); } private static void log(String aMessage){ System.out.println(aMessage); } } 

您可以尝试将UUID LSB和MSB一半作为长整数,并将其转换为数字。

我会考虑对System.nanoTime()进行简单的散列,假设你不介意哈希冲突的概率为1亿。

 long number = 0l; Random rand = new Random(); number = (rand.nextInt(1000000)+1000000000l) * (rand.nextInt(900)+100);