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