Skip to content

Instantly share code, notes, and snippets.

@rnapier
Last active Jan 12, 2019
Embed
What would you like to do?
import java.security.SecureRandom;
// Targeting Android SDK 19
// Goal is a (cryptographic) random long between 2^32 ..< 2^62.
// Ultimately I want to pick ~10M values with predictible and very low liklihood of collision (~0.001% Birthday Attack).
// Approach is to compute a random upper 32 bits between 1..<2^30 and add a lower 32-bits 0..<2^32.
// Need to be careful of lower 32 bits being treated as negative, since that would skew the results out of range.
public class MyRandom {
public static void main(String args[]) {
SecureRandom random = new SecureRandom();
// Compute upper 32 bits
int lowerBound = 1; // Don't allow zero; the minimum is 2^32, not 2^32 - 1
int upperBound = 1<<30; // Don't use upper two bits (2^62, not 2^64)
// Since we're not allowing upper values above 2^30, don't have to worry about signed/unsigned.
long upper = random.nextInt(upperBound - lowerBound) + lowerBound;
// Compute lower 32 bits. Want the entire 0..<2^32 range, not negatives.
long lower = Integer.toUnsignedLong(random.nextInt());
// Put them together. Remember + is higher precedence than <<.
long id = (upper << 32) + lower;
System.out.println(upper);
System.out.println(upper << 32);
System.out.println(lower);
System.out.println(id);
System.out.println(id >= (long)1<<32);
System.out.println(id < (long)1<<62);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment