Search code examples
javasecure-random

SecureRandom hash


I am trying to see if I can get a proper distribution based on secure random hash. I always seem to get double for my first index. Is there something wrong that I am doing

    SecureRandom sr = new SecureRandom();

    sr.setSeed(sr.generateSeed(16));
    int zero = 0;
    int one = 0;
    int two = 0;
    int three = 0;
    int four = 0;
    int five = 0;
    int six =0;


    for (int i = 0 ; i < 100000; i++) {
        long index = sr.nextLong()%6;
        if(index == 0)
            zero++;
        else if (index == 1)
            one++;
        else if(index == 2)
            two++;
        else if(index == 3)
            three++;
        else if(index == 4)
            four++;
        else if(index == 5)
            five++;
    }
    System.out.println(zero);
    System.out.println(one);
    System.out.println(two);
    System.out.println(three);
    System.out.println(four);
    System.out.println(five);
    System.out.println(six);

Take a look at the first line of the output

Here is the output
16548
8362
8314
8175
8272
8210

Solution

  • You're ignoring the fact that SecureRandom.nextLong() can return negatives. So your code is only catching half of all non-zero indexes because -7 % 6 == -1, but it's catching all zero indexes because -6 % 6 == 0.

    If you want all values to land between 0 and 5, just use Math.abs():

    long index = Math.abs(sr.nextLong()%6);
    

    Sample output:

    16735
    16510
    16657
    16776
    16599
    16723