algorithmoptimizationrandombinarybit-manipulation

Efficient seeded random shuffle for the bits in a 32-bit int?


Is there an algorithm that produces an efficient shuffle for a uint32 into a different uint32 that results in a 1:1 mapping when given a changeable random seed?

My initial direction on this is an algorithm where the seed somehow expresses what bits to rearrange in the number (so that 0000 0101 becomes 0100 1000 with the seed [0->6, 2->3]) but I'm not sure how to generate a way to do that shuffle efficiently.

Some constraints:


Solution

  • If the primary goal is to map all of the integers in the range [0..N] to arbitrary unique integers within the same range, then there's a fast, well-known way to do it: the multiplicative inverse.

    Eric Lippert wrote a blog post about it about 10 years ago, demonstrating how it works. It was part of his "Math from Scratch" series. Here's the first of the two articles about the multiplicative inverse: https://ericlippert.com/2013/11/12/math-from-scratch-part-thirteen-multiplicative-inverses/

    The algorithm has a one-time cost to calculate some coefficients, but then computing the inverse of any number is a matter of a few multiplications. It's fast.

    I use this algorithm when I need to obfuscate sequential keys. For example, the first user to sign up gets user id 1. Internally, that is. But the user id he sees might be 1879632. And the next user id is #2 internally. But the external user id that everybody sees is 5034832.

    The operation is reversible. Given the sequential id (i.e. '1'), you can generate the displayed user id (11879632). And, given the displayed user id, you can derive the sequential id.

    I also wrote a blog entry showing how to use it.