用密码

时间:2016-12-01 22:41:52

标签: lisp common-lisp

我正在编写一个通用的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)))) 

1 个答案:

答案 0 :(得分:0)

这是你的问题:

(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))))  

问题中的是带符号的列表,例如(Computer)。 使用此输入,encode-word在此列表的encode-char上调用car,即Computercdr为空,其余列表的递归为空返回NIL)。 但是,encode-char只会查看ch的第一个字符,因为它会调用(char (string ch) 0)。 我认为你需要encode-symbol,它会为符号名称的每个字符调用encode-char

但是,您的代码非常复杂。一些评论:

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

    (let alphabet (concatenate ...)
      (defun alphabet ()
        alphabet))
    
  • 正确缩进代码:http://people.ace.ed.ac.uk/staff/medward2/class/moz/cm/doc/contrib/lispstyle.html

  • 使用有意义的名字;有时短名称在上下文中是明确的,但像ch这样的两个字母缩写不是惯用的。它可以是ccharcharacter。此外,char-at正在撒谎,因为您计算了一个字符串。

  

我对如何制作编码符号功能感到有点困惑

对符号进行编码只是获取该符号的名称并对其进行编码;您可以使用symbol-namestring

(defun encode-symbol (symbol key) 
  (encode-string (string symbol) key))

现在,您可以实施encode-string

(defun encode-string (string key)
  (map 'string (lambda (c) (encode-char c key)) string))
  • 'stringMAP的返回类型。

  • (lambda ...)是一个匿名函数,为string序列中的每个字符调用。我使用它将key参数传递给encode-char