Advertisement
ksoltan

enigma2.0

Apr 27th, 2015
286
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scheme 6.83 KB | None | 0 0
  1. #lang racket
  2. ;; a rotor will be a list of 1) the settings 2) the numbers of times
  3. ;; it has rotated % 26 3) it's notch 4) the corresponding encryption
  4. (define alph (string->list "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))
  5.  
  6. (define rotor1 (string->list "EKMFLGDQVZNTOWYHXUSPAIBRCJ"))
  7. (define rotor2 (string->list "AJDKSIRUXBLHWTMCQGZNPYFVOE"))
  8. (define rotor3 (string->list "BDFHJLCPRTXVZNYEIWGAKMUSQO"))
  9. (define rotor4 (string->list "ESOVPZJAYQUIRHXLNFTGKDCMWB"))
  10. (define rotor5 (string->list "VZBRGITYUPSDNHLXAWMJQOFECK"))
  11.  
  12. (define refB (string->list "YRUHQSLDPXNGOKMIEBFZCWVJAT"))
  13. (define refC (string->list "FVPJIAOYEDRZXWGCTKUQSBNMHL"))
  14.  
  15. (define rI (list alph 0 (string->list "Q") rotor1))
  16. (define rII (list alph 0 (string->list "E") rotor2))
  17. (define rIII (list alph 0 (string->list "V") rotor3))
  18. (define rIV (list alph 0 (string->list "J") rotor4))
  19. (define rV (list alph 0 (string->list "Z") rotor5))
  20. (define rB (list alph 0 (list) refB))
  21. (define rC (list alph 0 (list) refC))
  22. (define a (list alph 0 (list) alph))
  23.  
  24. (define (make-rotor rotor times-rotated notch)
  25.   (list rotor times-rotated notch))
  26. (define (get-rotor-alph r) (car r))
  27. (define (get-times-rotated r) (cadr r))
  28. (define (get-rotor-notch r) (caddr r))
  29. (define (get-rotor-encrypt r) (cadddr r))
  30. ;; when rotor rotates: the times increments by 1, the rotor rotates once
  31. (define (rotate r) (list (rotate-rotor 1 (get-rotor-alph r))
  32.                          (modulo (+ 1 (get-times-rotated r)) 26)
  33.                          (get-rotor-notch r)
  34.                          (get-rotor-encrypt r)))
  35.  
  36. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  37.  
  38. ;; rotating the rotor
  39. (define (rotate-rotor times rotor)
  40.   ;; shift it all up one
  41.   (define (iter times to-shift r )
  42.     (if (= 0 times) (append r to-shift)
  43.         (iter (- times 1) (append to-shift (list (car r))) (cdr r))))
  44.   (iter times (list) rotor))
  45.  
  46. ;; the letter passed to the next rotor will not fall onto the same position
  47. ;; it depends on the number of times this rotor rotated and the next rotor
  48. ;; rotated; encryption before the reflector
  49.  
  50. (define (get-idx-next-letter-forward r1 r2 idx-letter-r1)
  51.   (get-alph-idx (modulo (+ (- idx-letter-r1 (get-times-rotated r1))
  52.              26
  53.              (get-times-rotated r2))
  54.           26)))
  55. ;; encryption after the reflector
  56. (define (get-idx-next-letter-backward r2 r1 idx-letter-r2)
  57.   (get-alph-idx (modulo (- (+
  58.               idx-letter-r2
  59.               (get-times-rotated r1))
  60.              (get-times-rotated r2))
  61.           26)))
  62. ;; the 0th (or 26th) index becomes Z, the first index is A
  63. (define (get-alph-idx idx-letter)
  64.   (if (= 0 idx-letter) 26 idx-letter))
  65.  
  66. ;; letter must be a char. Alphabet is a list from a string (list of chars)
  67. ;; gets the index of a specific letter in a sequence of letters
  68. (define (get-idx-of letter alphabet)
  69.   (define (iter count a)
  70.     (if (empty? a) -1
  71.     (if (equal? (car a) letter)
  72.         count
  73.         (iter (+ 1 count) (cdr a)))))
  74.   (iter 0 alphabet))
  75.  
  76. ;; gets letter at a specific index in a sequence of letters
  77. (define (get idx alphabet)
  78.   (define (iter count a)
  79.     (if (= 0 count) (car a) (iter (- count 1) (cdr a))))
  80.   (iter idx alphabet))
  81.  
  82. (define (pass-through-first-rotor r letter)
  83.   ;; returns the index + 1 of the letter in the alphabet to be passed to
  84.   ;; the second rotor
  85.   (+ 1 (get-idx-of
  86.         (get (get-idx-of
  87.               (get (get-idx-of letter alph) (get-rotor-alph r))
  88.               alph)
  89.              (get-rotor-encrypt r))
  90.         alph))
  91.   )
  92.  
  93. ;; returns the index of the letter starting from 1 (to use in index searching,
  94. ;; must subtract 1)
  95. ;; if r2 is empty, the idx-r2 should be from 0, otherwise, it is from 1
  96. ;; r2 is never going to be empty because if it is the last rotor, the reflector
  97. ;; will be passed
  98. (define (pass-through-rotor-forward r1 idx-r2 . r2)
  99.   (let ((idx (if (empty? r2) idx-r2
  100.                  (- (get-idx-next-letter-forward (car r2) r1 idx-r2) 1))))
  101.       (+ 1 (get-idx-of
  102.         (get (get-idx-of
  103.               (get idx (get-rotor-alph r1))
  104.               alph)
  105.              (get-rotor-encrypt r1))
  106.         alph))))
  107.  
  108. ;; index is from 1; returns index from 1
  109. (define (pass-through-rotor-backward r1 idx-r2 . r2)
  110.   (let ((idx (- (get-idx-next-letter-backward (car r2) r1 idx-r2) 1)))
  111.     (+ 1(get-idx-of (get
  112.                       (get-idx-of (get idx alph)
  113.                                   (get-rotor-encrypt r1))
  114.                       (get-rotor-alph r1))
  115.                 (get-rotor-alph r1)))))
  116.  
  117. ;; returns idx from 0
  118. (define (pass-forward r1 r2 r3 ref letter)
  119.   (define idx (get-idx-of letter alph))
  120.  (- (get-idx-next-letter-forward r3 ref (pass-through-rotor-forward
  121.                       r3
  122.                       (pass-through-rotor-forward
  123.                        r2
  124.                        (pass-through-rotor-forward r1 idx)
  125.                        r1)
  126.                       r2)) 1))
  127. ;; idx is from 0
  128. (define (pass-through-ref ref idx)
  129.   (+ 1 (get-idx-of (get idx (get-rotor-encrypt ref)) alph)))
  130.  
  131. ;; idx is from 1 return letter
  132. (define (pass-backward r1 r2 r3 ref idx)
  133.   (get (- (get-idx-next-letter-backward r1 a (pass-through-rotor-backward
  134.                    r1
  135.                    (pass-through-rotor-backward
  136.                     r2
  137.                     (pass-through-rotor-backward
  138.                      r3 idx ref)
  139.                     r3)
  140.                    r2)) 1) alph))
  141.  
  142. (define (encrypt-letter r1 r2 r3 ref letter)
  143.   (pass-backward r1 r2 r3 ref
  144.                  (pass-through-ref ref (pass-forward r1 r2 r3 ref letter))))
  145.  
  146. (define (encrypt r1 r2 r3 ref string)
  147.   (define str (string->list string))
  148.   (define (iter r1 r2 r3 ref string encoded)
  149.     ;; first must rotate all the rotors
  150.     (if (empty? string) (list->string encoded)
  151.         (if (= -1 (get-idx-of (car string) alph))
  152.             (iter r1 r2 r3 ref (cdr string) (append encoded
  153.                                                     (string->list " ")))
  154.             (let* ((r1first (car (get-rotor-alph r1)))
  155.                (r2first (car (get-rotor-alph r2)))
  156.                (r11 (rotate r1))
  157.                (r21 (if (or (equal? r1first (get-rotor-notch r1))
  158.                             (equal? r2first (get-rotor-notch r2)))
  159.                         (rotate r2) r2))
  160.                (r31 (if (equal? r2first (get-rotor-notch r2))
  161.                         (rotate r3) r3)))
  162.           (iter r11 r21 r31 ref (cdr string)
  163.                 (append encoded (list (encrypt-letter r11 r21 r31 ref
  164.                                                       (car string)))))))))
  165.   (iter r1 r2 r3 ref str (list)))
  166.  
  167. (provide alph rI rII rIII rIV rV rB rC get-idx-of get
  168.          get-idx-next-letter-forward get-idx-next-letter-backward
  169.          rotate pass-through-first-rotor pass-through-rotor-forward
  170.          pass-through-rotor-backward encrypt-letter pass-forward
  171.          pass-through-ref pass-backward encrypt)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement