我已经指出了我认为错误的地方。部分程序也通过我在下面写的评论进行了解释。
逻辑错误是整个加密消息是单个字母,这是用户输入的明文的第一个字母(即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
答案 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
。实际上没有必要显式组合行和列,只需按所需顺序切出所需的字符,将它们连接在一起并返回。