Skip to content

Instantly share code, notes, and snippets.

@eu90h
Last active June 26, 2023 14:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eu90h/664b68d3aa71ccd79930 to your computer and use it in GitHub Desktop.
Save eu90h/664b68d3aa71ccd79930 to your computer and use it in GitHub Desktop.
von Neumann extractor
#lang racket
; An implementation of the von Neumann unbiasing algorithm.
; The unbias procedure takes a pseudo-random bit generator and extracts entropy from the sequence of generated bits
; thereby creating a "more random" sequence.
; The catch here is that the pairs 01 and 10 have to be equally likely, and there can't be correlation between successive bits.
(define (extract-entropy bit-generator)
(let ([x (bit-generator)]
[y (bit-generator)])
(cond [(or (and (= x 1) (= y 1))
(and (= x 0) (= y 0)))
(extract-entropy bit-generator)]
[(and (= x 1) (= y 0)) 1]
[else 0])))
(define (unbias bit-generator)
(thunk (extract-entropy bit-generator)))
(define (bit-list->number bl)
(string->number (foldr string-append "" (map number->string bl)) 2))
(define (random-int bit-generator num-bits)
(bit-list->number
(let ([random-bit (unbias bit-generator)])
(let generate-bits ([bits-generated 0])
(if (= bits-generated num-bits)
null
(cons (random-bit)
(generate-bits (+ bits-generated 1))))))))
(module+ test
(random-int (thunk (random 2)) 32))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment