Lisp 与密码作斗争

Lisp 与密码作斗争,lisp,common-lisp,Lisp,Common Lisp,我正在编写一个公共lisp程序来加密和解密列表。我的问题是当我输入: (encode '((Computer)(Science)) 5) 它将只输出每个列表的第一个字母,例如H K。以下是我的代码: (defun alphabet () (concatenate 'string "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" "0123456789ABCDEFGHIJKLMNOPQRSTU

我正在编写一个公共lisp程序来加密和解密列表。我的问题是当我输入:

(encode '((Computer)(Science)) 5)  
它将只输出每个列表的第一个字母,例如H K。以下是我的代码:

(defun alphabet ()
  (concatenate 'string
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"))

(defun index-of (ch)
(position ch (alphabet)))

(defun char-at (position)
(subseq (alphabet) position (+ 1 position))) 

(defun encode-char (ch key)   
(char-at (+ (index-of (char(string ch)0)) key)))

 (defun encode-word (s key)
  (if s
    (concatenate 'string
      (encode-char (car s) key)
      (encode-word (cdr s) key))))  

(defun encode (list key)
  (if list
  (concatenate 'string
    (encode-word (car list) key)
    " "
    (encode (cdr list) key)))) 

(defun rindex-of (ch)
  (- (length (alphabet))
     (position ch (reverse (alphabet)))))

(defun decode-char (ch key)
  (char-at (- (rindex-of (char(string ch)0)) key)))

(defun decode-word (s key)
  (if s
    (concatenate 'string
      (decode-char (car s) key)
      (decode-word (cdr s) key))))  

(defun decode (list key)
  (if list
  (concatenate 'string
    (decode-word (car list) key)
    " "
    (decode (cdr list) key)))) 
这是你的问题:

(defun encode-char (ch key)   
  (char-at (+ (index-of (char(string ch)0)) key)))

(defun encode-word (s key)
  (if s
      (concatenate 'string
                   (encode-char (car s) key)
                   (encode-word (cdr s) key))))  
你问题中的一个单词是一个带有符号的列表,例如计算机。 使用此输入,encode word调用此列表的car上的encode char,即计算机的cdr为null,列表其余部分的递归返回NIL。 然而,encodechar只查看ch的第一个字符,因为它调用char字符串ch0。 我假设您需要encodesymbol,它将为符号名称的每个字符调用encodechar

但是,您的代码相当复杂。一些评论:

不要每次需要时都重新计算字母表。例如,定义一个闭包:

(let alphabet (concatenate ...)
  (defun alphabet ()
    alphabet))
正确缩进代码:

使用有意义的名字;有时短名称在上下文中是清楚的,但像ch这样的两个字母缩写不是惯用的。它可以是c、char或character。此外,char at是说谎的,因为您计算了一个字符串


我有点搞不清楚如何使用编码符号功能

编码一个符号就是获取该符号的名称并对其进行编码;您可以使用符号名或字符串:

现在,您可以实现编码字符串:

'字符串是的返回类型

拉姆达。。。是为字符串序列中的每个字符调用的匿名函数。我用这个来传递关键参数来编码字符


我会确保对字符串进行基本的编码/解码。其他一切都毫无意义。应避免输入结构中的混合。还要避免反复计算字母表

字母表是变量中的字符串:

(defvar *alphabet*
  (format nil
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~
     0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"))
编码功能:

(defun index-of (char alphabet)
  (position char alphabet))

(defun encode-char (char key alphabet)   
  (char alphabet
        (+ (index-of char alphabet) key)))

(defun encode-word (s key alphabet)
  (map 'string
       (lambda (char)
         (encode-char char key alphabet))
       s))
一个helper函数,用于连接一组被div分割的对象:

(defun join-to-string (list div)
  "Creates a new string of the elements of list with the div spliced in between."
  (with-output-to-string (s)
    (princ (first list) s)
    (loop for e in (rest list)
          do (princ div s) (princ e s))))

; CL-USER 6 > (join '(foo bar baz) '-)
; "FOO-BAR-BAZ"
对输入进行编码:

(defun encode (list-of-lists key alphabet)
  (join-to-string (mapcar (lambda (word)
                            (encode-word (string word) key alphabet))
                          (mapcan #'copy-list list-of-lists))
                  " "))
例如:

CL-USER 8 > (encode '((Computer Science) (Common Lisp)) 5 *alphabet*)
"HTRUZYJW XHNJSHJ HTRRTS QNXU"
风格

请注意,您希望缩进代码。做吧


的rindex正在浪费宝贵的周期。我们可以使用position和:from end t参数。

请修正缩进。如果您不介意给出提示的话,我对如何使用encode symbol函数有点困惑。我一直在尝试的是:encode char charstringcar s0 key,但我不确定如何获取列表的cdr。现在我得到了输出:STORE:H不适合,坏类型有什么建议吗?
(defun encode (list-of-lists key alphabet)
  (join-to-string (mapcar (lambda (word)
                            (encode-word (string word) key alphabet))
                          (mapcan #'copy-list list-of-lists))
                  " "))
CL-USER 8 > (encode '((Computer Science) (Common Lisp)) 5 *alphabet*)
"HTRUZYJW XHNJSHJ HTRRTS QNXU"