[ create a new paste ] login | about

Project: programmingpraxis
Link: http://programmingpraxis.codepad.org/1lKnWAtU    [ raw code | output | fork ]

programmingpraxis - Scheme, pasted on Jul 2:
; playfair

(define (string-upcase str)
  (list->string
    (map char-upcase
      (string->list str))))

(define (string-index c str)
  (let loop ((ss (string->list str)) (k 0))
    (cond ((null? ss) #f)
          ((char=? (car ss) c) k)
          (else (loop (cdr ss) (+ k 1))))))

(define (split plain-text)
  (let loop ((ps (string->list (string-upcase plain-text))) (x #\_) (xs '()))
    (cond ((null? ps) (if (char=? x #\_) (reverse xs)
                        (reverse (cons (string x #\X) xs))))
          ((not (char-alphabetic? (car ps))) (loop (cdr ps) x xs))
          ((char=? (car ps) #\J) (loop (cons #\I (cdr ps)) x xs))
          ((char=? x #\_) (loop (cdr ps) (car ps) xs))
          ((char=? (car ps) x) (loop ps #\_ (cons (string x #\X) xs)))
          (else (loop (cdr ps) #\_ (cons (string x (car ps)) xs))))))

(define (make-key pass-phrase)
  (let loop ((pass (string->list (string-append
              (string-upcase pass-phrase) "ABCDEFGHIKLMNOPQRSTUVWXYZ")))
             (key '()))
    (cond ((null? pass) (list->string (reverse key)))
          ((not (char-alphabetic? (car pass))) (loop (cdr pass) key))
          ((char=? (car pass) #\J) (loop (cons #\I (cdr pass)) key))
          ((member (car pass) key) (loop (cdr pass) key))
          (else (loop (cdr pass) (cons (car pass) key))))))

(define (encipher key plain-text)
  (define (p->c str)
    (let ((a (string-index (string-ref str 0) key))
          (b (string-index (string-ref str 1) key)))
      (cond ((= (quotient a 5) (quotient b 5)) ; same row
              (string (string-ref key (+ (* (quotient a 5) 5) (modulo (+ a 1) 5)))
                      (string-ref key (+ (* (quotient b 5) 5) (modulo (+ b 1) 5)))))
            ((= (modulo a 5) (modulo b 5)) ; same column
              (string (string-ref key (+ (* (modulo (+ (quotient a 5) 1) 5) 5) (modulo a 5)))
                      (string-ref key (+ (* (modulo (+ (quotient b 5) 1) 5) 5) (modulo b 5)))))
            (else (string (string-ref key (+ (* (quotient a 5) 5) (modulo b 5)))
                          (string-ref key (+ (* (quotient b 5) 5) (modulo a 5))))))))
  (apply string-append (map p->c (split plain-text))))

(define (decipher key cipher-text)
  (define (c->p str)
    (let ((a (string-index (string-ref str 0) key))
          (b (string-index (string-ref str 1) key)))
      (cond ((= (quotient a 5) (quotient b 5)) ; same row
              (string (string-ref key (+ (* (quotient a 5) 5) (modulo (- a 1) 5)))
                      (string-ref key (+ (* (quotient b 5) 5) (modulo (- b 1) 5)))))
            ((= (modulo a 5) (modulo b 5)) ; same column
              (string (string-ref key (+ (* (modulo (- (quotient a 5) 1) 5) 5) (modulo a 5)))
                      (string-ref key (+ (* (modulo (- (quotient b 5) 1) 5) 5) (modulo b 5)))))
            (else (string (string-ref key (+ (* (quotient a 5) 5) (modulo b 5)))
                          (string-ref key (+ (* (quotient b 5) 5) (modulo a 5))))))))
  (apply string-append (map c->p (split cipher-text))))

(display (encipher (make-key "PLAYFAIR") "PROGRAMMING PRAXIS"))
(newline)
(display (decipher (make-key "PLAYFAIR") "LIVOBLKZEDOELIYWCN"))


Output:
1
2
LIVOBLKZEDOELIYWCN
PROGRAMXMINGPRAXIS


Create a new paste based on this one


Comments: