我正在开发一个应用程序,我们需要生成一些唯一的数字,实际上没有预定义的限制所以使用java UUD生成器并且工作正常。 现在我们给出了生成12位唯一随机数的新要求。
任何人都可以指出一些好方法/算法来实现这一点,因为我在UUID生成的数字中看不到任何可能性。
提前致谢
答案 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);