Python:有没有好的方法检查文本是否被加密?
3 个回答
0
判断的方法之一是看填充。你可以在消息的末尾加上标准的填充。如果解密后的消息最后没有这个标准的填充,那说明用错了钥匙。反过来说,虽然不一定,但通常也是对的。
5
每种有名的加密方式都会产生看起来完全随机的输出。你可以利用这个特点,快速判断你处理的是加密文本还是某种未知协议的数据。如果数据是加密的,你可以检查你监听到的字节流中字节值的分布情况——如果所有的值分布得很均匀,那么很有可能你在处理的是加密文本。
为了更有把握,你可以进行更复杂的测试,比如分析字节对或字节组三个字节的分布等。
另一方面,你也可以将你感兴趣的特定语言的统计数据(比如字母组合的出现频率)与观察到的数据进行比较。如果你的数据表现得很相似,那么更有可能你看到的是明文(未加密的文本)。
16
没有绝对的方法可以判断,但实际上你可以做两件事:
检查是否有很多非ASCII字符(如果你期待别人发送的是英文文本的话)。
检查字符出现的分布。在正常文本中,有些字母比其他字母出现得更频繁。但在加密文本中,所有字符出现的概率大致相同。
简单的方法是查看是否有任何字符出现的次数超过了(N/256) + 5 * sqrt(N/256),其中N是字符的总数。如果超过这个次数,那很可能是自然语言(没有加密的文本)。
在Python中(反转上面的逻辑,当文本是加密时返回“真”):
def encrypted(text):
scores = defaultdict(lambda: 0)
for letter in text: scores[letter] += 1
largest = max(scores.values())
average = len(text) / 256.0
return largest < average + 5 * sqrt(average)
这个数学公式来源于平均数的高斯分布,方差等于平均数——虽然不是完美的,但应该足够接近。默认情况下(在文本量小的时候,这个方法不太可靠),这个方法会返回假(抱歉;之前我有一个错误的版本用“max()”,逻辑对于小数字是反的)。