我的Python方法不正确,跳过了列表中的项目(Playfair密码)

0 投票
3 回答
856 浏览
提问于 2025-04-16 14:23

我正在尝试写一个方法,这个方法需要一个密钥和一个字母表,然后创建一个“Playfair密码盒”。如果你不知道这是什么,它就是把密钥放进一个5 x 5的字母网格里,如果不够就换行,然后再加上字母表中剩下的字母。每个字母在这个盒子里只能出现一次。我想用一个包含5个内部列表的列表来实现,每个内部列表有5个项目。唯一的问题是,方法应该跳过某些字母,但它并没有做到。这里是我的方法和输出,谁能帮帮我呢?

def makePlayFair(key, alpha):
box = []
#join the key and alphabet string so that you only have to itterate over one string
keyAlpha = ""
keyAlpha = keyAlpha.join([key, alpha])
ind = 0
for lines in range(5):
    line = []
    while len(line) < 5:
        if isIn(keyAlpha[ind], box) or isIn(keyAlpha[ind], line):
            print(isIn(keyAlpha[ind],box))
            ind += 1
            continue
        else:
            line.append(keyAlpha[ind])
            ind += 1
    box.append(line)
return box

def isIn(item, block):
    there = None
    for each_item in block:

        if type(each_item) == type([]):
            for nested_item in each_item:
                if item == nested_item:
                    there = True
                    break
                else:
                    there = False
        else:       
            if item == each_item:
                there = True
                break
            else:
                there = False
    return there

>>> makePlayFair("hello", alphabet) #alphabet is a string with all the letters in it

> `[['h', 'e', 'l', 'o', 'a'], ['b', 'c', 'd', 'f', 'g'], ['h', 'i', 'j', 'k', 'l'], ['m', 'n', 'o', 'p', 'q'], ['r', 's', 't', 'u', 'v']]`

提前谢谢你的帮助!

祝好,brad

3 个回答

0

这是我尝试的结果:

#!/usr/bin/env python
from string import ascii_uppercase
import re

def boxify(key):
    cipher = [] 
    key = re.sub('[^A-Z]', '', key.upper())[:25]

    for i in range(max(25 - len(key), 0)):
            for letter in ascii_uppercase:
                if letter not in key:
                    key += letter
                    break

    for i in range(0, 25, 5):
        cipher.append(list(key[i:i+5]))

    return cipher


if __name__ == "__main__":
    print boxify("This is more than twenty-five letters, i'm afraid.")
    print boxify("But this isn't!")
1

首先创建一个字母的列表,然后把这些字母分成5行5列的网格:

def takeNatATime(n, seq):
    its = [iter(seq)]*n
    return zip(*its)

def makePlayfair(s):
    keystr = []
    for c in s + "abcdefghijklmnopqrstuvwxyz":
        if c not in keystr:
            keystr.append(c)
    return list(takeNatATime(5, keystr))

print makePlayfair("hello")

输出结果:

[('h', 'e', 'l', 'o', 'a'), ('b', 'c', 'd', 'f', 'g'), ('i', 'j', 'k', 'm', 'n'), ('p', 'q', 'r', 's', 't'), ('u', 'v', 'w', 'x', 'y')]
1

你的问题出在 isIn 这个地方:

你的 break 语句只会跳出里面的那个 for 循环。然后代码会继续执行外面的第二个 for 循环。这就意味着只有最后一个会被考虑到。你需要确保能够同时跳出两个循环,这样才能正确工作。

其实可以通过更简单的方法来实现,比如这样:

def makePlayFair(key, alpha):


    letters = []
    for letter in key + alpha:
        if letter not in letters:
            letters.append(letter)

    box = []
    for line_number in range(5):
        box.append( letters[line_number * 5: (line_number+1) * 5])

撰写回答