Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

BOFH excuse #438: sticky bit has come loose


comp / comp.lang.lisp / Vigenere

SubjectAuthor
o VigenereB. Pym

1
Subject: Vigenere
From: B. Pym
Newsgroups: comp.lang.lisp
Organization: A noiseless patient Spider
Date: Mon, 17 Jun 2024 15:32 UTC
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: No_spamming@noWhere_7073.org (B. Pym)
Newsgroups: comp.lang.lisp
Subject: Vigenere
Date: Mon, 17 Jun 2024 15:32:12 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 153
Message-ID: <v4pktn$nlmm$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
Injection-Date: Mon, 17 Jun 2024 17:32:12 +0200 (CEST)
Injection-Info: dont-email.me; posting-host="90b6bfd3931bdb2bad5411c6c3dc2474";
logging-data="775894"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18+tY9ZNqbtLeMTR3zgnDCQ"
User-Agent: XanaNews/1.18.1.6
Cancel-Lock: sha1:joWL7wuDUs5bLh/rAKV9EwXSqn4=
View all headers

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"

1

rocksolid light 0.9.8
clearnet tor