; http://cap-lore.com/code/Scheme/reposIntro/rc4.html (let ( ; (ex (lambda (m e) (write (list m e))(newline) e)) (Do ((fileVal "Do") 'Do))) (lambda (key) (let* ((sb (let ((s (make-string 256))) (Do 256 (lambda(n) (string-set! s n (integer->char n)))) (let ((len (string-length key))(j 0)) (Do 256 (lambda (k) (let ((i (- 255 k))) (set! j (bitwise-and (+ j (char->integer (string-ref s i)) (char->integer (string-ref key (modulo i len)))) 255)) (let ((t (string-ref s i))) (string-set! s i (string-ref s j)) (string-set! s j t)))))) (let ((i 0)(j 0)) (lambda () (set! i (bitwise-and (+ i 1) 255)) (let* ((a (string-ref s i))(ai (char->integer a))) (set! j (bitwise-and (+ j ai) 255)) (let ((b (string-ref s j))) (string-set! s i b)(string-set! s j a) (char->integer (string-ref s (bitwise-and (+ ai (char->integer b)) 255))))))))) (nb (lambda (n) (let r ((n n)(i 0)) (if (= 0 n) i (r (- n 1) (bitwise-ior (arithmetic-shift i 8) (sb)))))))) (let ((lst (list (cons 'nb nb) (cons 'sb sb) (cons 'rbi (lambda (n) ; random big integer less than n (if (= n 1) (lambda () 0) ; recursive function that returns a sufficiently large array (let* ((a (let ma ((as 0)(n (- n 1))) (if (= n 0) (make-vector as) (let ((nv (ma (+ as 1) (quotient n 256)))) (vector-set! nv as (bitwise-and n 255)) nv)))) (vl (vector-length a)) (fm (let pc ((p 1))(if (< (vector-ref a (- vl 1)) p) p (pc (+ p p)))))) ; (write (list 'dope vl (pt hd) n a hd))(newline) (lambda () (let sr () (let cd ((v 0)(ix vl)(td (lambda () (modulo (sb) fm)))(rn #f)) ; (write (list 'inter v ix lim fm))(newline) (if (= ix 0) v (let ((td (td))(lim (vector-ref a (- ix 1)))) (if (or rn (< td lim)) (cd (+ td (* 256 v)) (- ix 1) sb #t) (if (= td lim) (cd (+ td (* 256 v)) (- ix 1) sb #f) (sr)))))))))))) (cons 'U (let* ((p (expt 2 53)) (f (/ (exact->inexact p)))(m (- p 1))) (lambda () (* f (bitwise-and (nb 7) m)))))))) (lambda (sy) (cdr (assq sy lst))))))) ; tests (let ((Dos (fileVal "Do")) (g (((fileVal "RC4") "Seed stuff") 'sb))) ((Dos 'Do) (expt 2 20) (lambda (j) (g))) ((Dos 'DoL) 16 (lambda (j) (g)))) => (42 78 166 252 61 253 166 28 211 174 230 36 44 109 135 221) ; To corroborate http://en.wikipedia.org/wiki/RC4#Test_vectors (let* ((Do ((fileVal "Do") 'Do)) (gg (fileVal "RC4"))) (map (lambda (s) (let ((g ((gg s) 'sb))) (Do 16 (lambda (d) (display (substring (number->string (+ 256 (g)) 16) 1 3)))) (newline))) (list "Key" "Wiki" "Secret"))) => eb9f7781b734ca72a7194a2867b64295 6044db6d41b7e8e7a4d6f9fbd4428354 04d46b053ca87b594172302aec9bb992 (let ((m ((fileVal "RC4") "Seed stuff"))) (list ((m 'sb)) ((m 'sb)) ((m 'sb)))) => (205 217 98) ; m is the mutable state bearing object! (let ((t (lambda (n) (let* ((st ((fileVal "RC4") "fuxzz")) (Do ((fileVal "Do") 'Do)) (ar (make-vector n 0))(nb ((st 'rbi) n))) (Do (* n 1000) (lambda(d) (let ((k (nb))) (vector-set! ar k (+ 1 (vector-ref ar k)))))) ar)))) (list (t 11) (t 257) (t 16))) => (#11(998 1016 1029 1040 990 998 1002 1007 962 1003 955) #257(1006 954 1010 ... 1006 953 999) #16(997 1011 1026 1038 989 995 999 1002 958 997 950 1025 1027 996 1000 990)) (let ((g (((fileVal "RC4") "quat") 'U))) (let w ((n 100000) (s 0) (s2 0)) (if (= 0 n) (cons s s2) (let ((x (g))) (w (- n 1) (+ s x) (+ s2 (* x x))))))) ; => (49953.57990958937 . 33247.017526888936) ((((fileVal "RC4") "Seed stuff") 'rbi) 1); fails!