不使用 ord、chr 和循环的凯撒密码

Caesar Cipher without using ord, chr and loops

我在尝试解决这个问题时碰壁了,但我不确定如何解决这个问题。

我的想法是比较每个字符串的第一个字符,如果它们相同,则将该字符保存在索引位置移位的字母字符串中。 通过删除秘密的第一个字符来递归字符串的其余部分。如果第一个字符不同,则递归但删除字母字符串的第一个字符。

虽然我不确定如何递归字母表的其余部分。

alphabet = "abcdefghijklmnopqrstuvwxyz"

def caesar_encrypt(secret, shift):
    if len(secret) == 0:
        return "" 
    elif shift == 0:
        return secret
    else:
        if secret[0] == alphabet[0]:           
            return alphabet[shift] + caesar_encrypt(secret[1:],shift)
        else:
            return caesar_encrypt(secret,shift), alphabet[1:]

这个怎么样:

def shift_alphabet(shift):
    return alphabet[shift:] + alphabet[:shift]

def caesar_encrypt(secret, shift):
    coded_alphabet = shift_alphabet(shift)
    coded = [coded_alphabet[alphabet.index(i)] for i in secret]
    coded = ''.join(coded)

    return coded

使用 map/lambda 代替:

def shift_alphabet(shift):
      return alphabet[shift:] + alphabet[:shift]

def encrypt_letter(letter, coded_alphabet):
      return coded_alphabet[alphabet.index(letter)]

def caesar_encrypt(secret, shift):
      coded_alphabet = shift_alphabet(shift)
      coded = map(lambda x: encrypt_letter(x, coded_alphabet), secret)
      coded = ''.join(coded)

      return coded

我建议使用 str.index 来查找字符串中每个字符的每个字符在字母表中位置的索引。之后,使用它来索引字母表并递归。

您应该注意的几个问题:

  1. 如果字符串包含 space,请将此 space 原样放在字符串中,然后移动到下一个字符

  2. 你需要处理回绕,如果我们在字母表的末尾并且你选择了一个会超过字母表末尾的班次,你需要回绕并转到开头字母表。

这应该有效:

alphabet = "abcdefghijklmnopqrstuvwxyz"

def caesar_encrypt(secret, shift):
    if len(secret) == 0:
        return ""
    elif shift == 0:
        return secret
    elif secret[0] == ' ': # New - handle spaces
        return ' ' + caesar_encrypt(secret[1:], shift)
    else:
        index = (alphabet.index(secret[0]) + shift) % len(alphabet) # Find the right place to access the alphabet
        return alphabet[index] + caesar_encrypt(secret[1:], shift) # Use this new character then recurse

注意:此实现仅处理小写字母。