我正在研究cryptopals挑战(https://cryptopals.com/sets/1/challenges/3)的问题3(第1组)
我已经找到了密钥('x')并解密了消息('x'like a pound of bacon')
这是我的密码:
from hexToBase64 import hexToBinary
from fixedXOR import xorBuffers
def binaryToChar(binaryString):
asciiValue = 0
for i in range(int(len(binaryString))-1,-1,-1):
if(binaryString[i] == '1'):
asciiValue = asciiValue + 2**(7-i)
return chr(asciiValue)
def decimalToBinary(number):
binaryString = ""
while (number != 0):
bit = number % 2
binaryString = str(bit) + binaryString
number = int(number/2)
while(len(binaryString) < 8):
binaryString = "0" + binaryString
return binaryString
def breakSingleByteXOR(cipherString):
decryptedMess = ""
lowestError = 10000
realKey = ""
for i in range(0,128):
errorChar = 0
tempKey = decimalToBinary(i)
tempMess = ""
for j in range(0,len(cipherString),2):
#Take each byte of the cipherString
cipherChar = hexToBinary(cipherString[j:j+2])
decryptedChar = binaryToChar(xorBuffers(cipherChar,tempKey))
asciiValue = ord(decryptedChar)
if (not ((asciiValue >= 65) and (asciiValue <= 90)) \
or ((asciiValue >= 90) and (asciiValue <= 122)) \
or ( asciiValue == 32 )):
# if the character is not one of the characters ("A-Z" or "a-z"
# or " ") consider it as an "error"
errorChar += 1
tempMess = tempMess + decryptedChar
if(errorChar < lowestError):
lowestError = errorChar
decryptedMess = tempMess
realKey = chr(i)
return (realKey,decryptedMess)
if __name__ == "__main__":
print(breakSingleByteXOR("1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736"))
问题是,当我使用函数breakSingleByteXOR返回一个值(decryptedMess)时,结果是“像一磅培根一样煮mcS”
但是当我用函数返回2个值时(如上面的代码-(key,decryptedMess)),我收到了一个奇怪的结果('x','cOOKING\x00mc\x07S\x00LIKE\x00A\x00POUND\x00OF\x00BACON'),有人能解释一下为什么会这样吗?
Tbh,我正在学习python,因为我正在做挑战,所以希望我不会用这些代码触发任何人。。。。如果有人能给我一些关于编写好python代码的建议,我也会非常感激
谢谢各位:D
打印字符串中出现差异的原因确实是
print
函数的一个怪癖。你知道吗这个程序更深层次的问题是它没有产生正确的答案。这是因为试图确定解密字符是否在可接受范围内的大丑陋
if
是不正确的。你知道吗这在两个方面是不正确的。第一个是
(asciiValue >= 90)
应该是(asciiValue >= 97)
。编写所有这些表达式的更好方法是将它们表示为(asciiValue >= ord('a'))
和(asciiValue == ord(' '))
等等,这样就避免了难以理解的数字,从而避免了这种错误。你知道吗第二种方法是表达式没有正确分组。从他们的立场来看,他们是这样做的:
所以一些应该是好的字符(特别是从'a'到'z'和空格)被认为是坏的。要修复此问题,需要重新处理圆括号,以便条件为:
或者(这是你尝试的风格)
我不会给你精确的表达式来修复这个程序,你自己来解决会更好。(处理这种复杂性的一个好方法是将其移到一个单独的函数中,该函数返回
True
或False
。这使得测试您的实现是否正确变得很容易,只需使用不同的字符调用函数并查看结果是否符合您的要求。)当您得到正确的表达式时,您会发现程序发现了一个不同的“最佳密钥”,并且该密钥的解密字符串不包含任何行为与
print
异常的愚蠢越界字符。你知道吗print
函数是罪魁祸首—它在执行时将字符\x00
和\x07
转换为ASCII值。具体来说,这只在将字符串传递给print
函数时发生,而不是传递给iterable或其他对象(如tuple
)。你知道吗这是一个例子:
如果要将字符串
s
添加到iterable(tuple
、set
或list
)中,s
将不会由print
函数格式化:编辑
因为
\x00
和\x07
字节是ASCII控制字符,(\x00
是NUL,\x07
是BEL),所以不能用任何其他方式表示它们。因此,在不打印的情况下从字符串中删除这些字符的唯一方法之一是使用.replace()
方法;但是如果终端将\x00
字节视为空格,则必须使用s.replace('\x00', ' ')
来获得相同的输出,这现在改变了字符串的真实内容。你知道吗否则,在构建字符串时,您可以尝试实现一些逻辑来检查ASCII控制字符,或者不将它们添加到
tempMess
,或者添加不同的字符,如空格或类似字符。你知道吗参考文献
ASCII维基:https://en.wikipedia.org/wiki/ASCII
Curses模块:https://docs.python.org/3.7/library/curses.ascii.html?highlight=ascii#module-curses.ascii(如果您希望实现任何逻辑,可能会很有用)。你知道吗
相关问题 更多 >
编程相关推荐