; one-time pad
(define-syntax for
(syntax-rules ()
((for (var first past step) body ...)
(let ((ge? (if (< first past) >= <=)))
(do ((var first (+ var step)))
((ge? var past))
body ...)))
((for (var first past) body ...)
(let* ((f first) (p past) (s (if (< first past) 1 -1)))
(for (var f p s) body ...)))
((for (var past) body ...)
(let* ((p past)) (for (var 0 p) body ...)))))
(define (undigits ds . args)
(let ((b (if (null? args) 10 (car args))))
(let loop ((ds ds) (n 0))
(if (null? ds) n
(loop (cdr ds) (+ (* n b) (car ds)))))))
(define *n*
(let ((p 18446744073709551359)
(q 18446744073709551427))
(* p q)))
(define *s* 20131217) ; rip mom
(define (bbs)
(set! *s* (modulo (* *s* *s*) *n*))
(modulo *s* 2))
(define (rand-letter)
(let loop ((i 26) (ds (list)))
(if (positive? i)
(loop (- i 1) (cons (bbs) ds))
(let ((m (undigits ds 2)))
(if (< 67108860 m)
(rand-letter)
(integer->char
(+ (modulo m 26) 65)))))))
(define (one-time-pad rows cols)
(for (r 0 rows)
(for (c 0 cols)
(for (j 0 5)
(display (rand-letter)))
(display #\space))
(newline)))
(one-time-pad 40 6)