在Python中实现Caesar密码算法

时间:2017-02-02 22:11:25

标签: python algorithm for-loop iteration

所以我试图做一个代码,将一个单词中的每个字母移回字母表中的一些字母(包裹到最后)。例如,如果我想换2并输入CBE,我应该得到AZC。或者约翰进入HMFL。我有一个代码只能用于一个字母,我想知道是否有办法为python做一个嵌套for循环(这有效吗?)

def move(word, shift):
  alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
  original = ""
  for letter in range(26, len(alphabet)):
    if alphabet[letter] == word: #this only works if len(word) is 0, I want to be able to iterate over the letters in word.
        original += alphabet[letter-shift]
  return original

4 个答案:

答案 0 :(得分:5)

你可以这样开始

def move(word, shift):
    alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    return "".join([alphabet[alphabet.find(i)-shift] for i in word])

基本上,这个列表理解构造了单个字母的列表。然后,通过.find方法找到字母表中字母的索引。 (索引 - 移位)是所需的新索引,它是从字母表中提取的。生成的列表再次加入并返回。

请注意,它显然不适用于小写输入字符串(如果您希望使用str.upper方法)。实际上,这个词应该只包含字母表中的字母。对于句子,方法需要以不同方式处理空格。

答案 1 :(得分:2)

请勿在字母中找到方式的字母 - 通过索引操作找到它。让 char 成为有问题的信件:

alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
...
char_pos = alphabet.index(char)
new_pos = (char_pos - shift) % len(alphabet)
new_char = alphabet[new_pos]

一旦理解了这一点,就可以将这三行折叠成一行。

现在,让它对整个单词进行操作......

new_word = ""
for char in word:
    # insert the above logic
    new_word += new_char

你能把所有这些碎片放在一起吗?

您仍然需要检查 char 是否是一封信。此外,如果您有兴趣,可以为所有已翻译的字符构建列表理解,并应用&#39;。#。()来获取新单词。< / p>

例如......

如果字母在字母表中(如果是字母表中的字母),请移动给定的距离并获取新的字母,如果需要,可以在末尾包裹(%26)。如果它不是大写字母,那么请使用原始字符。

从所有这些翻译中创建一个列表,然后将它们连接成一个字符串。返回那个字符串。

def move(word, shift):
    alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    return ''.join([alphabet[(alphabet.find(char) - shift) % 26]
               if char in alphabet else char 
               for char in word])

print move("IBM", 1)
print move("The 1812 OVERTURE is COOL!", 13)

输出:

HAL
Ghe 1812 BIREGHER is PBBY!

答案 2 :(得分:1)

A_VAL = ord('a')

def move(word, shift):
    new_word = ""
    for letter in word:
        new_letter = ord(letter) - shift
        new_word += chr(new_letter) if (new_letter >= A_VAL) else (26 + new_letter)
    return new_word

请注意,这仅适用于小写字词。一旦你开始混合大写和小写字母,你就需要开始检查它们。但这是一个开始。我放弃了你的嵌套循环想法,因为如果可能的话你应该避免使用它们。

答案 3 :(得分:0)

您可以使用:chr()为您提供ascii编号的字符,ord()为您提供匹配字符的ascii编号。

这是一个古老的Vigenere项目:

def code_vigenere(ch,cle):
    text = ch.lower()
    clef = cle.lower()
    L = len(cle)
    res = ''

    for i,l in enumerate(text):
        res += chr((ord(l) - 97 + ord(cle[i%L]) - 97)%26 +97)

    return res