加密程序中索引的逻辑错误
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。
我已经指出了我认为错误的地方。部分程序也通过我在下面写的评论进行了解释。
逻辑错误是整个加密信息是一个字母,是用户输入的明文的第一个字母(即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。