Commit e0c73a8d authored by Tim McNamara's avatar Tim McNamara

Update generate-a-random-range.md

parent 34806263
......@@ -17,7 +17,19 @@ def rand_range(start, end):
return start + (proportion * diff)
```
When we need to generate the proportion ourselves, there is more work to do:
When we need to generate the proportion ourselves, there is more work to do.
In `random_bytes()` we read a fixed number of random bytes. On UNIXy operating
systems, we can read from the pseudo-file `/dev/urandom`. Those bytes are passed
through to `rand_from_bytes()`.
`rand_from_bytes()` uses lots of quirky syntax and some trickery. It uses Python's
`struct` module to interpret the bytes as unsigned integers using [Python's rules for doing so](https://docs.python.org/3/library/struct.html#format-characters).
`r / (1 << 8*n_bytes)` might look like black magic, but all it's doing is generating
a proportion for us. `(1 << 8*n_bytes)` is the maximum integer value for whatever type
that we care about. We use that as a denominator. `r` lies somewhere between 0 and `(1 << 8*n_bytes)`.
Python will return a floating point number because of the division.
And now we're back where we started wiith when calling `random.random()`.
```python
def random_bytes(n_bytes, source='/dev/urandom'):
......@@ -30,12 +42,12 @@ def rand_from_bytes(n_bytes):
entropy = random_bytes(n_bytes)
typecode = {1: 'B', 2: 'H', 4: 'I', 8: 'Q'}[n_bytes]
r, = struct.unpack(typecode, entropy)
r, = struct.unpack(typecode, entropy)
return r / (1 << 8*n_bytes)
def rand_range(start, end):
diff = end - start
proportion = rand_from_bytes()
proportion = rand_from_bytes(4)
return start + (proportion * diff)
```
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment