fork download
  1. ; password generator
  2.  
  3. (define-syntax when
  4. (syntax-rules ()
  5. ((when pred? expr ...)
  6. (if pred? (begin expr ...)))))
  7.  
  8. (define rand ; knuth random number generator with shuffle box
  9. (let* ((a 69069) (c 1234567) (m 4294967296) (k 32) ; 32-bit
  10. ; (a 6364136223846793005) (c 1442695040888963407)
  11. ; (m 18446744073709551616) (k 256) ; 64-bit
  12. (seed 19380110) ; Happy Birthday DEK
  13. ;(seed (time-second (current-time)))
  14. (next (lambda ()
  15. (set! seed (modulo (+ (* a seed) c) m)) seed))
  16. (init (lambda (seed) (let ((box (make-vector k)))
  17. (do ((j 0 (+ j 1))) ((= j k) box)
  18. (vector-set! box j (next))))))
  19. (box (init seed)))
  20. (lambda args
  21. (when (pair? args)
  22. (set! seed (modulo (car args) m)) (set! box (init seed)))
  23. (let* ((j (quotient (* k seed) m)) (n (vector-ref box j)))
  24. (set! seed (next)) (vector-set! box j seed) (/ n m)))))
  25.  
  26. (define (randint . args)
  27. (let ((lo (if (pair? (cdr args)) (car args) 0))
  28. (hi (if (pair? (cdr args)) (cadr args) (car args))))
  29. (inexact->exact (+ lo (floor (* (rand) (- hi lo)))))))
  30.  
  31. (define (shuffle x)
  32. (do ((v (list->vector x)) (n (length x) (- n 1)))
  33. ((zero? n) (vector->list v))
  34. (let* ((r (randint n)) (t (vector-ref v r)))
  35. (vector-set! v r (vector-ref v (- n 1)))
  36. (vector-set! v (- n 1) t))))
  37.  
  38. (define (genrand count chars)
  39. (let ((len (string-length chars)))
  40. (do ((k count (- k 1))
  41. (ps (list) (cons (string-ref chars (randint len)) ps)))
  42. ((zero? k) ps))))
  43.  
  44. (define (pgen lower upper digit special)
  45. (let ((lowers (genrand lower "abcdefghijklmnopqrstuvwxyz"))
  46. (uppers (genrand upper "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
  47. (digits (genrand digit "0123456789"))
  48. (specials (genrand special "!@#$%^&*()")))
  49. (list->string (shuffle
  50. (append lowers uppers digits specials)))))
  51.  
  52. (display (pgen 5 2 3 0)) (newline)
Success #stdin #stdout 0.01s 8124KB
stdin
Standard input is empty
stdout
zvMh0m6n2J