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

时间:2017-01-05 12:53:56

标签: python encryption python-3.4

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

逻辑错误是整个加密消息是单个字母,这是用户输入的明文的第一个字母(即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

1 个答案:

答案 0 :(得分: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替换为indexOfText的6份副本。您不需要从列表中删除元素,然后插入新元素。相反,只需

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

而不是两步

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

尽管您仍然会对所有indexOfText使用相同的i存在逻辑错误。

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

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

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