使用列表而不是字符串来移动密码

时间:2014-10-27 13:09:30

标签: scheme

我想在Scheme中编写Shift或Caesar密码,但不使用字符串。我想改用一个列表:

(define message '(T H E F O X))
(define k 4)
(define A(char->integer #\A))
(define Z(char->integer #\Z))

(define (cipher message)
  (if (empty? message)
      '()
      (begin
        (display ((+ (char->integer (car message)) k))->char)
        (cipher (cdr message))
        )
      ))

(define (helper)
  (cipher message))

我知道缺少我应该使用模数并与A和Z的限制进行比较的部分,但我的问题是如何将(汽车信息)转换为字符然后转换为整数,所以我可以添加k的值;然后将它从整数转换回char以显示其值。

我找到了基于字符串和地图的解决方案,但是如何只使用列表和上面的转换呢?

提前致谢

4 个答案:

答案 0 :(得分:1)

所以我的理解是你想要处理符号。

让我们从序言开始:

(define A (char->integer #\A))
(define Z (char->integer #\Z))
(define MOD (+ Z (- A) 1)) ; 26, used for modulo

MOD已被添加,因为我们需要获取shift modulo 26的结果。现在我们需要将符号转换为整数并返回的过程:

(define (symbol->integer s)
  (char->integer (car (string->list (symbol->string s)))))

(define (integer->symbol i)
  (string->symbol (list->string (list (integer->char i)))))

测试:

> (symbol->integer 'A)
65
> (integer->symbol 65)
'A

最后是cipher程序。我更喜欢将k作为参数:

(define (cipher message k)
  (if (empty? message)
      '()
      (cons (integer->symbol (+ A (modulo (+ k (- (symbol->integer (car message)) A)) MOD)))
            (cipher (cdr message) k))))

测试:

> (cipher '(T H E F O X) 4)
'(X L I J S B)

答案 1 :(得分:1)

这是一个允许列表,符号,字符串和字符的通用版本。请注意,我没有手动编写循环(因为这样做对我来说很痛苦,因为map很容易获得);欢迎你自己做。

此版本使用SRFI 13(适用于string-map)和SRFI 26(适用于cut)。 (如果您手动编写循环,并手动扩展cut,那么您将能够在普通方案中使用它。)

(require srfi/13 srfi/26)   ;; for Racket

(define (caesar x shift)
  (cond ((char? x) (caesar-char x shift))
        ((string? x) (caesar-string x shift))
        ((symbol? x) (caesar-symbol x shift))
        ((list? x) (caesar-list x shift))
        (else (error "Unknown type" x))))

(define (caesar-char ch shift)
  (if (char-alphabetic? ch)
      (let* ((ord (char->integer ch))
             (lower (modulo ord 32))
             (upper (- ord lower)))
        (integer->char (+ upper (modulo (+ lower shift) 26))))
      ch))

(define (caesar-string str shift)
  (string-map (cut caesar-char <> shift) str))

(define (caesar-symbol sym shift)
  (string->symbol (caesar-string (symbol->string sym) shift)))

(define (caesar-list lst shift)
  (map (cut caesar <> shift) lst))

示例:

> (caesar '(T H E F O X) 4)
'(X L I J S B)
> (caesar '(X L I J S B) 22)
'(T H E F O X)

答案 2 :(得分:0)

你的message不是由字符组成的。这是一个符号列表。测试一下:

(char? (car '(T H E F O X)))
#f
(symbol? (car '(T H E F O X)))
#t

首先,您需要列出字符列表:

(char? (car '(#\a #\b)))
#t

你的另一个问题是语法。你不能这样写->char。此外,你有一对额外的parens。 您正在尝试应用char->integer和k之和的数字。

(display ((+ (char->integer (car message)) k))->char)   

这将是一个有效的版本:

(display (integer->char (+ (char->integer (car message)) k)))

答案 3 :(得分:0)

  1. 使用symbol->stringstring-append创建一个消息列表字符串。
  2. 在消息字符串上运行您需要的任何加密算法以获取加密版本。
  3. 使用string-refstring->symbol将结果作为列表。