2

I have a user case which involves generating a number which a user enters into a website to link a transaction to their account.

So I have the following code which generates a random 12 digit number:

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;
}

This method takes in two params which are generated by a DB.

What I need to understand is:

  1. Is this random? I have a test which ran this method 1 million times and it always seem to be random.

  2. Can I cut this down to 8 characters?

Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110
user2859250
  • 71
  • 1
  • 3
  • It can be random but have collisions. What you want is the least amount of collisions. – Sotirios Delimanolis Oct 08 '13 at 15:28
  • 8
    The first rule of cryptography is don't do your own cryptography. Okay, so this is a hash that you want to yield a random/unique number and not cryptography per se. How about using a GUID instead? Have a look at this question: http://stackoverflow.com/questions/325443/generate-uuid-in-java – Bob Kaufman Oct 08 '13 at 15:30
  • 1
    it's based on time with a simple algorithm, does not looks random but predictable. – LMC Oct 08 '13 at 15:33
  • It is "sorta random". Sufficient, perhaps, for seeding a game, but not for anything where the value must be truly unpredictable. Among other things, the probability of a "1" as the right-most digit is greater than random selection would predict. – Hot Licks Oct 08 '13 at 15:34
  • "Is this random? I have a test which ran this method 1 million times and it always seem to be random." -> this does not make much sense :)) Either you prove that the distribution is random [by actually computing it], either you prove that there are no periodic repetition in the pretended randomness. Anyway use existing algorithms. – moonwave99 Oct 08 '13 at 15:36

2 Answers2

3

No it is neither unique nor random.

It is not "random" in the sense of highly entropic / uncorrelated with other values.

The only source of non-determinism is System.nanoTime, so all the entropy comes from a few of the least significant bits of the system clock. Simply adding numbers like 1232 and 5465 does not make the result less correlated with subsequent results.


Is this random? I have a test which ran this method 1 million times and it always seem to be random.

If this code is used in multiple threads on the same machine, or on multiple machines with synced clocks, you will see duplicates more quickly.

Since there is low entropy, you are likely to see duplicates by random chance fairly quickly. Math.se addresses the likelihood depending on how many of these you generate.


Can I cut this down to 8 characters?

Only if you don't lose entropy. Consider two ways of truncating a timestamp:

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);

Since it is a straightforward calculation from an increasing counter, an attacker who can try multiple times can predict the value produced in a way that they would not be able to had you used a crypto-strong random number generator like java.util.SecureRandom.

Community
  • 1
  • 1
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • @tucuxi, if the seed is the system time, and you're starting a data-center full of machines up at the same, then you can still get problems with machines generating identical sequences in lock-step. – Mike Samuel Oct 08 '13 at 15:50
2

Is this random?

You are asking, is your function based on System.nanoTime() a random number generator (RNG)?

The definition of RNG is: generator, which generates numbers that lack any pattern.

So, are numbers returned from your function without any pattern?

No, they have an easily-observable pattern, because they depend on System.nanoTime() (system clock).

Can I cut this down to 8 characters?

Yes, you can, but it's still not random. Adding or padding won't help too.

Use SecureRandom instead.

Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110