Python:有没有一种好方法可以检查文本是否加密?

2024-04-30 00:48:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在玩cryptocat,这是一个有趣的在线聊天服务,允许你用密钥加密你的消息,这样只有拥有相同密钥的人才能阅读你的消息。该服务的一个有趣的方面(在我看来)是这样一个事实,即使用您所使用的密钥以外的密钥加密的文本只显示为“[加密]”,而不是一堆垃圾密码文本。我的问题是,在Python中,有没有一种好方法可以确定给定的文本是否是密文?我在这个例子中使用RC4,因为它是我能实现的最快的东西(基于Wikipedia上的伪代码)。谢谢。在


Tags: 方法代码文本消息密码密钥wikipedia例子
3条回答

每一个值其名的密码都会产生看起来完全随机的输出。您可以利用这一事实进行快速测试,无论您处理的是加密文本还是遵循某种未知协议的数据。如果数据是加密的,那么你可以检查字节流中字节值的分布情况—如果所有的值都是均匀分布的,那么你很有可能在处理加密文本。在

为了对这个决定越来越有信心,你可以把测试扩展到更复杂的领域,比如分析字节对或三元组的分布等等

另一方面,您还可以将您感兴趣的特定语言的图表和三角图上的统计数据与您观察到的数据中出现的数据进行比较(另请参见here)。如果您的数据行为类似,那么您更可能观察到的是纯文本。在

没有一种可靠的方法可以判断,但实际上你可以做两件事:

  1. 检查是否有许多非ascii字符(如果您希望人们发送英文文本)。

  2. 检查数值分布。在普通文本中,有些字母比其他字母更常见。但在加密文本中,所有字符的可能性都差不多。

后一种简单的方法是查看是否有任何字符出现超过(N/256)+5*sqrt(N/256)次(总共有N个字符),在这种情况下,它很可能是一种自然语言(未加密)。在

在python中(与上面的逻辑相反,加密时为“true”):

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)

数学的基础是平均数是平均数的高斯分布,方差等于平均数——这并不完美,但可能已经足够接近了。默认情况下(在不可靠的情况下,使用少量的文本)这将返回false(抱歉;之前我有一个错误的版本,其中“max()”对于小数字的逻辑是错误的)。在

一种方法是填充。在邮件末尾添加标准填充。如果解密后的消息没有以标准填充结束,则使用错误的密钥解密。相反的情况不能保证,但通常是正确的。在

相关问题 更多 >