Search code examples
algorithmoptimizationlanguage-agnosticrandombit-manipulation

Most efficient method of generating a random number with a fixed number of bits set


I need to generate a random number, but it needs to be selected from the set of binary numbers with equal numbers of set bits. E.g. choose a random byte value with exactly 2 bits set...

00000000 - no
00000001 - no
00000010 - no
00000011 - YES
00000100 - no
00000101 - YES
00000110 - YES
...

=> Set of possible numbers 3, 5, 6...

Note that this is a simplified set of numbers. Think more along the lines of 'Choose a random 64-bit number with exactly 40 bits set'. Each number from the set must be equally likely to arise.


Solution

  • Do a random selection from the set of all bit positions, then set those bits.

    Example in Python:

    def random_bits(word_size, bit_count):
        number = 0
        for bit in random.sample(range(word_size), bit_count):
            number |= 1 << bit
        return number
    

    Results of running the above 10 times:

    0xb1f69da5cb867efbL
    0xfceff3c3e16ea92dL
    0xecaea89655befe77L
    0xbf7d57a9b62f338bL
    0x8cd1fee76f2c69f7L
    0x8563bfc6d9df32dfL
    0xdf0cdaebf0177e5fL
    0xf7ab75fe3e2d11c7L
    0x97f9f1cbb1f9e2f8L
    0x7f7f075de5b73362L