simple method for timestamp and nonce


Some internet protocols such as OAuth need timestamps and nonces.

Here comes what 8. Nonce and Timestamp saids in OAuth Core 1.0 Revision A,

Unless otherwise specified by the Service Provider, the timestamp is expressed in the number of seconds since January 1, 1970 00:00:00 GMT. The timestamp value MUST be a positive integer and MUST be equal or greater than the timestamp used in previous requests.
The Consumer SHALL then generate a Nonce value that is unique for all requests with that timestamp. A nonce is a random string, uniquely generated for each request. The nonce allows the Service Provider to verify that a request has never been made before and helps prevent replay attacks when requests are made over a non-secure channel (such as HTTP).

Some just use System.nanoTime().

Let’s do something. As of writing this entry, System.currentTimeMillis() gave me 1354169632072 which has 23 high zero bits.

current millis
    1354169632072
    0x13B4ACCC548
    Thu Nov 29 15:13:52 KST 2012
    0000 0000 0000 0000 0000 0001 0011 1011
    0100 1010 1100 1100 1100 0101 0100 1000

left shift by 3
    10833357056576
    0x9DA56662A40
    Sat Apr 19 10:50:56 KST 2313
    0000 0000 0000 0000 0000 1001 1101 1010
    0101 0110 0110 0110 0010 1010 0100 0000

left shift by 20
    1419949776119529472
    0x13B4ACCC54800000
    Tue Feb 24 15:32:09 KST 44998387
    0001 0011 1011 0100 1010 1100 1100 1100
    0101 0100 1000 0000 0000 0000 0000 0000

Note that shifting 3 bits serves about 300 years.
We can have, by shifting 20 bits, free 20 bits for random number with given timestamps.


// <20-bit shifted current millis> | <20-bit random>

// 000T TTTT TTTT TTTT TTTT TTTT TTTT TTTT
// TTTT TTTT TTTT NNNN NNNN NNNN NNNN NNNN

// this method will be valid for about 300 years
// possibility of collisions: one in a million in the very same millisecond

final long nonce =
    (System.currentTimeMillis() << 20)
    | ThreadLocalRandom.current().nextInt(1048576);

Here are some methods.

public static long nonce(final long timestamp, final Random random) {
    return (timestamp << 20) | random.nextInt(1048576);
}

public static long nonce(final long timestamp) {
    return nonce(timestamp, ThreadLocalRandom.current());
}

public static long nonce(final Random random) {
    return nonce(System.currentTimeMillis(), random);
}

public static long nonce() {
    return nonce(System.currentTimeMillis(), ThreadLocalRandom.current());
}

Leave a comment