Vigenere

Liste des GroupesRevenir à cl lisp 
Sujet : Vigenere
De : No_spamming (at) *nospam* noWhere_7073.org (B. Pym)
Groupes : comp.lang.lisp
Date : 17. Jun 2024, 17:32:12
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <v4pktn$nlmm$1@dont-email.me>
User-Agent : XanaNews/1.18.1.6
Pascal J. Bourguignon wrote:

tristanhennequin <tristanhennequin@free.fr> writes:
 
Hello,
I 've just read the vigenere implementation published on rosetta code :
 
I think it's very long and maybe clumsy.
 
It's also wrong.
 
(defun strip (s)
  (remove-if-not
    (lambda (c) (char<= #\A c #\Z))
    (string-upcase s)))
 
There may be non alphabetic characters between A and Z.  This functions
rightfully doesn't use alpha-char-p, (because alpha-char-p may contain
implementation defined characters), but it is wrong in using this simple
comparison.  Since we only want letters from A to Z, we must write it
explicitely (or, possibly check that only letters from A to Z are
between A and Z, but I have my doubts if this check can be done at
compilation time).
 
So:
 
(defparameter alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
 
(defun strip (s)
  (remove-if-not (lambda (c) (find (char-upcase c) alphabet)) s)
 
 
 
(defun vigenère (s key &key decipher
&aux (A (char-code #\A))
     (op (if decipher #'- #'+)))
 
Personnally, I don't like using &aux for stylistic reasons (it puts in
the signature of the function details that belong to the implementation.
It's very rare to find a case where having those variable in the
signature is justified.  &aux is basically a ugly hack to do stuff in
struct constructors).
 
 
  (labels
    ((to-char (c) (code-char (+ c A)))
     (to-code (c) (- (char-code c) A)))
 
Again, this part makes a lot of assumptions that may be wrong.  A better
implementation is:
 
      (to-char (code) (aref     code alphabet))
      (to-code (char) (position char alphabet))
 
    (let ((k (map 'list #'to-code (strip key))))
      (setf (cdr (last k)) k)
      (map 'string
   (lambda (c)
     (prog1
       (to-char
(mod (funcall op (to-code c) (car k)) 26))
       (setf k (cdr k))))
   (strip s)))))
 
This is not bad.  What you can do here, is to use pop:
 
    (map 'string
           (lambda (c) (to-char (mod (funcall op (to-code c) (pop k)) 26)))
           (strip s))
 
 
(let* ((msg "Beware the Jabberwock... The jaws that... the claws that
catch!")
       (key "vigenere cipher")
       (enc (vigenère msg key))
       (dec (vigenère enc key :decipher t)))
  (format t "msg: ~a~%enc: ~a~%dec: ~a~%" msg enc dec))
 
 
 
What is the most concise and short version of the vigenere encryption
method can you produce in lisp?
 
(defparameter alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
 
(defun strip-non-letters (string)
  (remove-if-not (lambda (c) (find (char-upcase c) alphabet)) string))
 
(defun ensure-circular (list)
  (setf (cdr (last list)) list))
 
(defun vigenère (text key &key decipher) 
  (flet ((to-char (code) (aref     alphabet code))
         (to-code (char) (position char alphabet :test (function char-equal))))
    (declare (inline to-char to-code))
    (let ((op      (if decipher (function -) (function +)))
          (offsets (ensure-circular (map 'list (function to-code) (strip-non-letters key)))))
      (map 'string
           (lambda (c) (to-char (mod (funcall op (to-code c) (pop offsets)) 26)))
           (strip-non-letters text)))))
 
  (let* ((msg "Beware the Jabberwock... The jaws that... the claws that catch!")
         (key "vigenere cipher")
         (enc (vigenère msg key))
         (dec (vigenère enc key :decipher t)))
    (format t "msg: ~a~%enc: ~a~%dec: ~a~%" msg enc dec))
 
 
msg: Beware the Jabberwock... The jaws that... the claws that catch!
enc: WMCEEIKLGRPIFVMEUGXXYILILZXYVBZLRGCEYAIOEKXIZGU
dec: BEWARETHEJABBERWOCKTHEJAWSTHATTHECLAWSTHATCATCH
--> nil

Gauche Scheme

(use srfi-1) ;; circular-list

(define alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZ")

(define (text->list str)
  (filter-map
    (lambda (c)
      (let ((x (char-upcase c))) (string-scan alphabet x)))
    (string->list str)))

(define (list->text lst)
  (list->string
    (map
      (lambda (n) (string-ref alphabet n))
      lst)))
 
(define (vig text key encrypt?)
  (list->text
    (map
      (lambda(n k) (mod ((if encrypt? + -) n k) 26))
      (text->list text)
      (apply circular-list (text->list key)))))

(vig "Beware the Jabberwock... The jaws that... the claws that catch!"
  "vigenere cipher" #t)
  ===>
"WMCEEIKLGRPIFVMEUGXXYILILZXYVBZLRGCEYAIOEKXIZGU"

(vig "WMCEEIKLGRPIFVMEUGXXYILILZXYVBZLRGCEYAIOEKXIZGU"
  "vigenere cipher" #f)
  ===>
"BEWARETHEJABBERWOCKTHEJAWSTHATTHECLAWSTHATCATCH"

(vig "W M C E EIKLGRPIFVMEUGXXYILILZXYVBZLRGCEYAIOEKXIZGU"
  "vigenere cipher" #f)
  ===>
"BEWARETHEJABBERWOCKTHEJAWSTHATTHECLAWSTHATCATCH"


Date Sujet#  Auteur
17 Jun 24 o Vigenere1B. Pym

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal