java唯一编号少于12个字符

时间:2013-10-08 15:27:54

标签: java

我有一个用户案例,涉及生成用户输入网站以将交易链接到其帐户的号码。

所以我有以下代码生成一个随机的12位数字:

public String getRedemptionCode(long utid, long userId) {       
    long nano = System.nanoTime();      
    long temp = nano + utid + 1232;
    long redemptionCode = temp + userId + 5465;     
    if (redemptionCode < 0) {
        redemptionCode = Math.abs(redemptionCode);
    }       
    String redemptionCodeFinal = StringUtils.rightPad(String.valueOf(redemptionCode), 12, '1');
    redemptionCodeFinal = redemptionCodeFinal.substring(0, 12);
    return redemptionCodeFinal;
}

此方法接受由DB生成的两个参数。

我需要了解的是:

  1. 这是随机的吗?我有一个测试,它运行这个方法100万次,它似乎总是随机的。

  2. 我可以将其减少到8个字符吗?

2 个答案:

答案 0 :(得分:3)

不,它既不是唯一也不是随机的。

在高度熵/与其他价值无关的意义上,它不是“随机的”。

非确定性的唯一来源是System.nanoTime,因此所有熵都来自系统时钟的一些最低有效位。只需添加12325465等数字,就不会使结果与后续结果的相关性降低。


  

这是随机的吗?我有一个测试,它运行这个方法100万次,它似乎总是随机的。

如果在同一台机器上的多个线程中使用此代码,或者在具有同步时钟的多台机器上使用此代码,您将更快地看到重复项。

由于熵较低,您可能会很快通过随机机会看到重复。 Math.se根据您生成的可能性来解决可能性。


  

我可以将其减少到8个字符吗?

只有你没有失去熵。考虑两种截断时间戳的方法:

long time = ...;   // Least significant bits have randomness.
String s = "" + time;
// Cut off the right-most, most entropic bits
String bad = time.substring(0, 8);
// Cut off the left-most, least entropic bits
String better = time.substring(time.length() - 8);

由于这是一个来自增加计数器的简单计算,一个可以多次尝试的攻击者可以预测所产生的价值,使他们无法使用crypto-strong random number generator之类的java.util.SecureRandom {{1}} }。

答案 1 :(得分:2)

  

这是随机的吗?

您问,您的功能是基于System.nanoTime()随机数生成器(RNG)吗?

RNG的定义是:generator,它生成缺少任何模式的数字

那么,你的函数返回的数字是否没有任何模式?

不,他们有一个易于观察的模式,因为它们依赖于System.nanoTime()system clock)。

  

我可以将其减少到8个字符吗?

是的,你可以,但它仍然不是随机的。添加或填充也无济于事。

改为使用SecureRandom