Bab
Bab

Reputation: 443

Randomly initialize BitSet with specific length

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.

Upvotes: 1

Views: 538

Answers (3)

Josemy
Josemy

Reputation: 838

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

Upvotes: 0

Jacob G.
Jacob G.

Reputation: 29680

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.

Upvotes: 0

Guss
Guss

Reputation: 32315

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

Upvotes: 1

Related Questions