Encryption 如何计算位字符串的近似熵?

Encryption 如何计算位字符串的近似熵?,encryption,entropy,information-theory,data-compression,Encryption,Entropy,Information Theory,Data Compression,有没有标准的方法可以做到这一点 谷歌搜索——发现了多篇学术论文,但我只想找到一段伪代码,定义任意长度的给定位字符串的近似熵 (如果说起来容易做起来难,这取决于应用程序,我的应用程序涉及16320位加密数据(cyphertext)。但加密为一个谜题,并不意味着无法破解。我想我应该先检查熵,但无法很容易地找到熵的良好定义。因此,这似乎是一个应该在StackOverflow上解决的问题!关于从何处开始解加密16k随机位的想法也很受欢迎……) 另请参见此相关问题: 我相信答案是正确的。 这不仅不能用一大

有没有标准的方法可以做到这一点

谷歌搜索——发现了多篇学术论文,但我只想找到一段伪代码,定义任意长度的给定位字符串的近似熵

(如果说起来容易做起来难,这取决于应用程序,我的应用程序涉及16320位加密数据(cyphertext)。但加密为一个谜题,并不意味着无法破解。我想我应该先检查熵,但无法很容易地找到熵的良好定义。因此,这似乎是一个应该在StackOverflow上解决的问题!关于从何处开始解加密16k随机位的想法也很受欢迎……)

另请参见此相关问题:

我相信答案是正确的。 这不仅不能用一大块伪代码来解释,而且Kolmogorov的复杂性也不是问题

在实践中,您可以做的一件事是使用最佳可用算法压缩位字符串。 压缩越大,熵越低。

是标准的计算方法。下面是一个简单的Python实现,不知羞耻地从代码库复制,因此获得了GPL许可:

导入数学
定义熵(字符串):
“计算字符串的香农熵”
#获取字符串中字符的概率
prob=[float(string.count(c))/len(string)表示dict.fromkeys(list(string))]
#计算熵
熵=-sum([p*math.log(p)/math.log(2.0)表示prob中的p])
返回熵
def熵_理想值(长度):
“计算给定长度字符串的理想香农熵”
prob=1.0/长度
返回-1.0*length*prob*math.log(prob)/math.log(2.0)

请注意,此实现假定您的输入位流最好以字节表示。您的问题域可能是这样,也可能不是这样。您真正想要的是将比特流转换为一个数字字符串。你如何决定这些数字是特定领域的。如果您的数字实际上只是1和0,那么将您的比特流转换为1和0的数组。但是,您选择的转换方法将影响您获得的结果。

没有单一的答案。熵总是相对于某个模型。当有人说密码的熵是有限的时,他们的意思是“相对于智能攻击者的预测能力”,这总是一个上限

你的问题是,你试图测量熵来帮助你找到一个模型,这是不可能的;熵度量可以告诉你一个模型有多好


话虽如此,有一些相当通用的模型,你可以尝试;它们被称为压缩算法。如果gzip可以很好地压缩数据,那么您至少找到了一个可以很好地预测数据的模型。例如,gzip对简单的替换几乎不敏感。它可以处理文本中的“wkh”,就像处理“the”一样简单。

熵不是你得到的字符串的属性,而是你本来可以得到的字符串的属性。换句话说,它限定了生成字符串的过程

在简单的情况下,从一组N个可能的字符串中得到一个字符串,其中每个字符串都具有与其他字符串相同的被选择概率,即1/N。在这种情况下,该字符串的熵称为N。熵通常以位表示,这是一个对数标度:“N位”的熵等于2n


例如:我喜欢将密码生成为两个小写字母,然后是两个数字,然后是两个小写字母,最后是两个数字(例如
va85mw24
)。字母和数字是随机、统一且相互独立选择的。此过程可能会产生26*26*10*10*26*26*26*10*10=456976000个不同的密码,所有这些密码被选择的机会均等。这样一个密码的熵是4569760000,这意味着大约32.1位。

NIST随机数生成器评估工具包有一种计算“近似熵”的方法。以下是简短的描述:

近似熵测试说明:此测试的重点是 每个重叠m位模式的频率。目的 该测试旨在比较两组重叠块的频率 与预期结果相反的连续/相邻长度(m和m+1) 对于一个随机序列

更详细的解释可从本页的:


这里有一个Python实现(我还将其添加到了Wiki页面):


上述示例与使用单词的香农熵的下列公式一致:

这里有一个O(n)算法来计算它:

import math
from collections import Counter


def entropy(s):
    l = float(len(s))
    return -sum(map(lambda a: (a/l)*math.log2(a/l), Counter(s).values()))

啊,谢谢你!但这需要知道位字符串中的单词长度?例如,如果我假设16320位实际上是2040字节,我可以将其应用于我的字符串。编辑答案以提供有关信息如果你只转换为1和0,那么该算法不会将“0101010101…”视为具有最大可能熵吗?根据cypherpunks答案,这假设了一个模型,其中每个字符在每个位置的可能性相等。@fmark@dreeves信息熵取决于可用状态的数量。由于二进制字符串只有两种可能的状态,最大熵总是1。我不确定我是否理解你的第二段。这是正确的,但我可能没有正确地问这个问题。看到我给出的答案了吗?这也许表明了我想问的问题。但我认为它实际上可能是指一个比特串的“近似熵”的标准。无论如何,这个答案是有用和相关的;谢谢@Specializet答案对字符有限制,因此可用的字母表不是密码中每个字符都有36个字符。对于来自36个字符的字母表的无限制8字符密码,
>>> U = np.array([85, 80, 89] * 17)
>>> ApEn(U, 2, 3)
-1.0996541105257052e-05
import math
from collections import Counter


def entropy(s):
    l = float(len(s))
    return -sum(map(lambda a: (a/l)*math.log2(a/l), Counter(s).values()))