1
votes

I have two BitSets which have to be initialized randomly with the length of 20 bits.

I am trying to achieve that by initializing the BitSets with 20 bits each and within a for loop iterating through the BitSets and call nextBoolean() of the Random class. However, the length is not always 20. So, I have been playing around with it, and figured it that it might be because it does not count the false bits as part of the length. In case I understand it correctly, how do I force it to have 20 random bits always?

public static void generate() {

        BitSet set1 = new BitSet(20);
        BitSet set2 = new BitSet(20);

        Random r = new SecureRandom();
        for (int i = 0; set1.length() < 20 && set2.length() < 20; i++) {
            set1.set(i, r.nextBoolean());
            set2.set(i, r.nextBoolean());
        }

        StringBuilder s = new StringBuilder();
        for (int i = 0; i < set1.length(); i++) {
            s.append(temp1.get(i) == true ? 1 : 0);
        }

        System.out.println(s + " " + s.length() + " " + set1.length() + " "+ set2.length());
}

Thanks in advance.

3
if you always want 20 as your size, why not use a constant? Something like final int size = 20;. Then you can replace all occurrences of 20 with size - user3170251
Thanks for you suggestion. I have tried that, but it did not resolve the problem, unfortunately. The length is still inconsistent and now it goes above 20 sometimes - Bab
Take a look at stackoverflow.com/a/69148389/139985. Basically, the Bitset class model represents a bitset with an infinite number of bits. The "logical length" returned by length() denotes the position of the rightmost ONE bit. So your idea of a bitset with precisely 20 bits randomly 0 or 1 does not fit the model. (Or to put it another way, its length() may not be 20.) - Stephen C

3 Answers

0
votes

In case I understand it correctly, how do I force it to have 20 random bits always?

Change your for-loops to:

for (int i = 0; i < 20; i++) {
    set1.set(i, r.nextBoolean());
    set2.set(i, r.nextBoolean());
}

...

for (int i = 0; i < 20; i++) {
    s.append(temp1.get(i) == true ? 1 : 0);
}

A BitSet is backed by a long[] and all bits are initially set to false, so calling BitSet#length will not return the value 20 unless the 19th bit happens to be set, as stated by its documentation:

Returns the "logical size" of this BitSet: the index of the highest set bit in the BitSet plus one. Returns zero if the BitSet contains no set bits.

By using the value 20 as the condition in your for-loops, you're ensuring that the first 20 bits will have the opportunity of being set randomly.

0
votes

Why not use Bitset.valueOf(byte[] array) to initialize the bit set from a random byte array?

Something like:

public BitSet getBits(SecureRandom sr, int size) {
    byte[] ar = new byte[(int) Math.ceil(size / 8F)];
    sr.nextBytes(ar);
    return BitSet.valueOf(ar).get(0, size);
}
0
votes

If you are using Java 7, you can initialize a random byte array with Random.nextBytes(byte[]) then use the static BitSet.valueOf(byte[]) method to create a BitSet from the same byte array.

Random rnd = new Random();
// ...
byte[] randomBytes = new byte[NUM_BYTES];
rnd.nextBytes(randomBytes);
return BitSet.valueOf(randomBytes);

Credits for: https://stackoverflow.com/a/8566871/5133329