12位Java中的数字唯一随机数生成

时间:2011-01-11 09:14:40

标签: java

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

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

提前致谢

11 个答案:

答案 0 :(得分:27)

通过调用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));
}

答案 1 :(得分:3)

(long)Math.random()*1000000000000L

但是有碰撞的可能性

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


编辑:感谢bence olah,我解决了一个令人毛骨悚然的错误

答案 2 :(得分:2)

使用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();
}

答案 3 :(得分:1)

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

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编码器。也许你想用简单的东西取而代之,但除此之外它就能完成这项工作。

答案 4 :(得分:1)

Random random = new Random();
Math.round(random.nextFloat() * Math.pow(10,12))

答案 5 :(得分:0)

您可以尝试这样做。这会生成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);
  }
}

答案 6 :(得分:0)

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

答案 7 :(得分:0)

下面是最好的解决方案,我尝试了多种组合后写了。 下面是12位数字的唯一ID。...对于每个调用,多个线程也会返回唯一ID。

谢谢 CH.K M V Prasad *

private static int counter=0;
private static int oldMinute=-1;
private static int minIncr=0;


private static String repeatNumber(String repeatString ,int numberOftimes) {
    String returnStr="";
    for(int indexCounter=0;indexCounter<numberOftimes;indexCounter++) {
        returnStr+=repeatString;
    }
    return returnStr;
}

public synchronized static String getUniqueID() {

    System.out.println("curr Mill "+System.currentTimeMillis()+"D:"+(2020%1000)+"-"+(2021));
    Calendar cal = Calendar.getInstance();
    if(oldMinute==-1 || oldMinute< cal.get(Calendar.MINUTE) ) {
        oldMinute=cal.get(Calendar.MINUTE);
        minIncr=0;
        counter=0;
    }else if(counter==99) {
        System.out.println("99 counter ");
        oldMinute=cal.get(Calendar.MINUTE)+(++minIncr);
        counter=0;
    }
    String uId=cal.get(Calendar.HOUR_OF_DAY)+""+cal.get(Calendar.MONTH)+""+(cal.get(Calendar.YEAR)%100)+""+oldMinute+""+cal.get(Calendar.DATE);
    String incrCounter=""+(++counter);
    int appendZeros=uId.length()+incrCounter.length();
    System.out.println("Uid="+uId+",incrCounter="+incrCounter+" , tolalZero="+appendZeros);
    return uId+repeatNumber("0", 12-appendZeros)+incrCounter;

}

答案 8 :(得分:0)

您可以简单地使用

Random generator = new Random(System.currentTimeMillis());
return generator.nextLong() % 1000000000000;

这会将结果限制为12位数字。

答案 9 :(得分:-1)

我会考虑对System.nanoTime()进行简单的散列,假设您不介意哈希冲突的可能性为10亿。

答案 10 :(得分:-2)

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