加密程序中索引的逻辑错误

Logical Error with Indexing in Encryption Program

我已经指出了我认为错误的地方。部分程序也通过我在下面写的评论进行了解释

逻辑错误是整个加密信息是一个字母,是用户输入的明文的第一个字母(即string[0])。 for 循环一定有问题,它将明文插入到行数组中,但没有正确地遍历明文字符串。

row1 = [' ', ' ', ' ', ' ', ' ', ' '] #initialise the rows as arrays
row2 = [' ', ' ', ' ', ' ', ' ', ' ']
row3 = [' ', ' ', ' ', ' ', ' ', ' ']
row4 = [' ', ' ', ' ', ' ', ' ', ' ']
row5 = [' ', ' ', ' ', ' ', ' ', ' ']
row6 = [' ', ' ', ' ', ' ', ' ', ' ']
def updateRow(aList, text, index): #function for removing spaces and inserting plaintext letters
    indexOfText = text[index]
    for i in range(1,7): #logic error in this loop
        aList.remove(' ')
        aList.insert(i, indexOfText)
    return aList
def createColumn(row1, row2, row3, row4, row5, row6, index): #function for creating columns by adding the rows with the same index
    column = row1[index] + row2[index] + row3[index] + row4[index] + row5[index] + row6[index]
    return column
def encrypt(col1, col2, col3, col4, col5, col6): #function for adding the columns together to produce the enciphered message
    cipher = col1 + col2 + col3 + col4 + col5 + col6
    return cipher  
while True:
    plaintext = input("Enter you message:") #input plaintext
    row1Pop = updateRow(row1, plaintext, 0) #populate rows with plaintext
    ... #continues
    row6Pop = updateRow(row6, plaintext, 0)
    column1 = createColumn(row1Pop, row2Pop, row3Pop, row4Pop, row5Pop, row6Pop, 0) #create required columns
    ... #continues   
    column6 = createColumn(row1Pop, row2Pop, row3Pop, row4Pop, row5Pop, row6Pop, 5)
    ciphertext = encrypt(column1, column2, column3, column4, column5, column6) #create final encrypted message
    print(ciphertext) #display encrypted message
    break

示例输入为:

this is my first attempt at it today

并且此输出变为:

tttttttttttttttttttttttttttttttttttt

输出应该是这样的(如果程序运行正常):

tsit  h rtatimsetosytm d   piaifatty

如果你想用标准 Python 实现你想要做的事情,你可以这样做:

def encrypt(p):
    #assumes len(p) <= 36
    #larger message needs to be broken into blocks of 36

    p += ' '*(36-len(p)) #pad with spaces if needed
    rows = [p[6*i:6*i+6] for i in range(6)] #slice into substrings of length 6
    columns = zip(*rows) #zip processes the rows in parallel
    return ''.join(''.join(column) for column in columns)

#test:

print(encrypt('this is my first attempt at it today'))

#prints 'tsit  h rtatimsetosytm d   piaifatty'

我不希望您完全理解,但它提供了 Python 的工作原理。尽可能地,列表应该 assembled 通过推导式。为了逐个字符地处理字符串,没有必要将字符读入列表。在上面的代码中,rows 只是一个包含 6 个长度为 6 的字符串的列表。如果您还不熟悉列表理解,您可以像这样在循环中构建它:

rows = []
for i in range(6):
    rows.append(p[6*i:6*i+6])

密文的构建方式有点难以解释。如果您想以更基本的方式这样做,请使用嵌套 for 循环(注意两个循环的顺序):

ciphertext = ''
for j in range(6) #iterate over the columns
    for i in range(6) #iterate over rows
        ciphertext += rows[i][j]
return ciphertext

至于你的原始代码,我不太清楚如何保存它。您提到的 for 循环很奇怪,您说它有错误是正确的。请注意 indexOfText 在循环本身期间不会更新。因此,您正在 aList 替换为 indexOfText 的 6 个副本。您不需要从列表中删除一个元素然后插入一个新元素。相反,只需

aList[i] =  indexOfText #but use 0-based indexing

而不是 2 步

aList.remove(' ')
aList.insert(i, indexOfText)

尽管您仍然会遇到对所有 i.

使用相同 indexOfText 的逻辑错误

顺便说一下,ecrypt 可以通过使用 slice operator 中的可选 step 字段变得更短:

def encrypt2(p):
    p += ' '*(36-len(p))
    return ''.join(p[i:36:6] for i in range(6))

这在功能上等同于 encrypt。确实不需要显式assemble行和列,只需按照你想要的顺序切出你想要的字符,将它们连接在一起,然后return。