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

问题描述 投票:1回答:1

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

逻辑错误是整个加密消息是单个字母,它是用户输入的明文的第一个字母(即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 encryption python-3.4
1个回答
2
投票

如果你想用标准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的工作方式。应尽可能通过理解来组合列表。为了逐个字符处理字符串,不必将字符读入列表。在上面的代码中,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替换为6份indexOfText。您不需要从列表中删除元素,然后插入新元素。相反,简单地说

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

而不是两步

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

虽然你仍然会有所有indexOfText使用相同的i的逻辑错误。

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

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

这在功能上等同于encrypt。实际上不需要显式组合行和列,只需按所需顺序切出所需的字符,将它们连接在一起并返回。

© www.soinside.com 2019 - 2024. All rights reserved.