December SPECIAL! For a limited time only. Get 20% discount on a LIFETIME PRO account!Want more features on Pastebin? Sign Up, it's FREE!
tweet
Guest

Untitled

By: a guest on Oct 4th, 2015  |  syntax: Scheme  |  size: 3.83 KB  |  views: 17  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print  |  QR code  |  clone
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. ; The letters of the alphabet
  2. (define alphabet '(a b c d e f g h i j k l m n o p q r s t u v w x y z))
  3.  
  4. ; Get the index of a symbol in a list
  5. (define (index-of s l)
  6.   (define (iter i l)
  7.     (cond
  8.       ((null? l) -1)
  9.       ((eq? (car l) s) i)
  10.       (else (iter (+ i 1) (cdr l)))))
  11.   (iter 0 l))
  12.  
  13. ; Advance a digit in the space of 0 through 25
  14. (define (advance-digit n) (remainder (+ n 1) 26))
  15.  
  16. ; Stateful version of map
  17. (define (map! f l)
  18.   (if (not (null? '()))
  19.     (begin
  20.       (set-car! l (f (car l)))
  21.       (map! f (cdr l)))))
  22.  
  23. ; Assoc using the cdr instead of the car of the pairs
  24. (define (back-assoc x l)
  25.   (cond
  26.     ((null? l) #f)
  27.     ((= (cdar l) x) (car l))
  28.     (else (back-assoc x (cdr l)))))
  29.  
  30. ; Make a rotor from a list of mappings
  31. (define (make-rotor mapping)
  32.    (define pos 0)
  33.  
  34.    ; Advance the rotor by one; Return wether the next one should advance as
  35.    ; well
  36.    (define advance
  37.      (begin
  38.        (map!
  39.         (lambda (pair)
  40.           (cons
  41.             (advance-digit (car pair))
  42.             (advance-digit (cdr pair))))
  43.         mapping)
  44.        (set! pos (advance-digit pos))
  45.        (= pos 0)))
  46.  
  47.    ; Map the characters before reflecting
  48.    (define (map-forward n)
  49.      (cdr (assoc n mapping)))
  50.  
  51.    ; Map the characters after reflecting
  52.    (define (map-backwards n)
  53.      (cdr (back-assoc n mapping)))
  54.  
  55.    ; Set the rotor position to the supplied number
  56.    (define (set-to n)
  57.      (if (not (= (+ pos 1) n))
  58.        (advance)
  59.        (set-to n)))
  60.  
  61.    (define funs
  62.      (list
  63.        (cons 'advance advance)
  64.        (cons 'map-forward map-forward)
  65.        (cons 'map-backwards map-backwards)
  66.        (cons 'set-to set-to)))
  67.  
  68.    ; The dispatch function
  69.    (define (rotor s . args)
  70.      (if (assoc s funs)
  71.        (apply (cdr (assoc s funs)) args)
  72.        (error "Invalid symbol:" s)))
  73.  
  74.    rotor)
  75.  
  76. ; Both the plugboard and the reflector can be abstracted to a rotor that
  77. ; doesn't turn
  78. (define make-plugboard make-rotor)
  79. (define make-reflector make-rotor)
  80.  
  81. ; Make an enigma from a plugboard, some rotors and a reflector
  82. (define (make-enigma plugboard rotors reflector)
  83.   ; Advance all rotors that need to be advanced
  84.   (define (advance l)
  85.     (if (not (null? l))
  86.         (if ((car l) 'advance) (advance (cdr l)))))
  87.  
  88.   ; Do the digit transformation step before the reflection
  89.   (define (step-move d)
  90.     (define (iter d l)
  91.       (if (null? l)
  92.         d
  93.         (iter ((car l) 'map-forward d) (cdr l))))
  94.     (iter d (cons plugboard rotors)))
  95.  
  96.   ; Reflect the digit
  97.   (define (reflect d)
  98.     (reflector 'map-forward d))
  99.  
  100.   ; Do the digit transformation after the reflection
  101.   (define (backwards-step d)
  102.     (define (iter l)
  103.       (if (null? l)
  104.         d
  105.         ((car l) 'map-backwards (iter (cdr l)))))
  106.     (iter (append rotors (list plugboard))))
  107.  
  108.   ; Encrypt a digit
  109.   (define (encrypt-digit d)
  110.     ((advance rotors)
  111.      (backwards-step
  112.       (reflect
  113.        (forward-step d)))))
  114.  
  115.   ; Encrypt a message
  116.   (define (encrypt message)
  117.     (map
  118.       (lambda (num) (list-ref alphabet num))
  119.       (map encrypt-digit
  120.            (map (lambda (s) (index-of s alphabet)) message))))
  121.  
  122.   ; Set the rotors to a certain position
  123.   (define (set-rotors positions)
  124.     (define (iter positions rotors)
  125.       (cond
  126.         ((null? rotors) 'done)
  127.         ((null? positions) 'done)
  128.         (else
  129.           (begin
  130.             ((car rotors) 'set-to (car positions))
  131.             (iter (cdr positions) (cdr rotors))))))
  132.     (iter positions rotors))
  133.  
  134.   (define funs
  135.     (list
  136.       (cons 'encrypt encrypt)
  137.       ; En- and Decrypting are the same in an engima
  138.       (cons 'decrypt encrypt)
  139.       (cons 'set-rotors set-rotors)))
  140.  
  141.    ; The dispatch function
  142.    (define (enigma s . args)
  143.      (if (assoc s funs)
  144.        (apply (cdr (assoc s funs)) args)
  145.        (error "Invalid symbol:" s)))
  146.  
  147.   enigma)
clone this paste RAW Paste Data
Top