# Deterministically combine more than one source of entropy

What is the proper/canonical way to do this?

For example, $$0 < r1 < 1$$ and $$0 < r2 < 1$$. Presuming uniformly distributed probabilities for the two, combining/averaging them is going to bias very quickly towards $$0.5$$.

The specific use case I have is a game/simulation I'm programming. An entity has a random number it was given that's specific to it; Their individual behaviours also have random numbers associated with them. For the purposes of most behavioural calculations, I only use the behaviour random number, but for a few I want to incorporate the entity's random number. Simply averaging them will result in less randomness.

### Desired Outcome : Deterministically combine more than one source of entropy

So “Entity A” may have a small random number, and so most of its attributes are skewed small. It's behaviour random number happens to be big, so most of its behaviour attributes are skewed large. When combined the two random numbers deterministically result in $$n$$, and so some of its behaviour attributes skew towards $$n$$.

### RE: Off-Topic

My question is not specific to game development. The particular use case is. How do cryptographers deterministically combine sources of entropy? I assume they have uses case for this outcome.

• can't you just hash them and map the hash to 0..1? Jan 4, 2014 at 23:18
• @CodesInChaos huh, yes I could. Is that the proper way to combine two sources of entropy? [fwiw, it's javascript, so I have Math.random for free, but would need to implement sha1/another hash in code.]
Jan 4, 2014 at 23:27
• I think the canonical way to combine two numbers uniformly distributed between 0 and n is to just add them mod n. (Eg, XOR is often used for doing so, and it is just bitwise addition mod 2.) In the case of floating point, however, it may introduce precision bias due to precision limitations. Jan 5, 2014 at 0:18
• cleaned up some comments Jan 8, 2014 at 14:04
• Note of dangers of combining many sources of entropy for cryptography: blog.cr.yp.to/20140205-entropy.html Feb 10, 2014 at 16:35

Set $r = r_1 + r_2 - \mathsf{floor}(r_1 + r_2)$. One (possible) advantage of this approach is that the result will be uniformly random in [0, 1] even if only one of $r_1$, $r_2$ is uniformly random. (Assuming the two values are independent.)

In Python you can also express this as

r = (r1 + r2) % 1.0

• In some languages there is a frac(x) which equals x - floor(x) for non-negative values of x (I'm not sure how it behaves for negative values) Jan 6, 2014 at 18:58

Combining two independent random variables that are uniformly distributed between $0$ and $2^n-1$ is rather easy: Both are $n$-bit numbers and every bit is set to $1$ with probability $\frac12$. Therefore, the same is true for their exclusive OR, which will also be uniformly distributed between $0$ and $2^n-1$.

Now, JavaScript's Math.random() pseudo-randomly returns a number in $(0,1)$. Converting that number into an integer $n$-bit integer is easy enough:

var r1 = Math.floor(Math.random() * Math.pow(2,n));


$n$ cannot be greater than 32 in my browser (other implementations may vary) or the resulting integer will always be even.

Now, to combine two of those integers, you can use exclusive OR:

var r = r1 ^ r2;


JavaScript operates on signed 32-bit integers, so $n$ has to be less than 31 to avoid wrapping and signs.

To convert the obtained integer into a value in $(0,1)$, just do this:

r = (r + 1/2) / Math.pow(2,n);

• Awesome, thanks! any reference you can provide regarding the 0 -- 2^n - 1 would be appreciated!
• hah, sry, when I first saw that expression, I was thinking it was something like a trigonometric identity (e.g. 1 - sin^2 x); But I see now it's just a reference to binary order-of-magnitude.
• The sum of r1 and r2 will have an Irwin–Hall distribution, which is not at all uniform. Jan 5, 2014 at 4:22