【问题标题】:How do I compute the approximate entropy of a bit string?如何计算位串的近似熵?
【发布时间】:2011-02-28 01:56:35
【问题描述】:

有标准的方法吗?

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

(如果说起来容易做起来难,并且取决于应用程序,我的应用程序涉及 16,320 位加密数据(密文)。但加密为一个谜题,并不意味着不可能破解。我想我会首先检查熵,但不容易找到一个好的定义。所以这似乎是一个应该在 StackOverflow 上的问题!也欢迎从哪里开始解密 16k 随机看似位的想法......)

另请参阅此相关问题:
What is the computer science definition of entropy?

【问题讨论】:

    标签: encryption entropy information-theory data-compression


    【解决方案1】:

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

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

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

    【讨论】:

    • 这是正确的,但我可能没有正确地提出这个问题。请参阅我给出的答案,这可能表明我要问的问题。但我认为实际上引用位串的“近似熵”可能是标准的。无论如何,这个答案是有用且相关的;谢谢!
    • @specializt 答案对字符有限制,因此可用的字母不是密码中每个字符的 36 个字符。对于 36 个字符的字母表中不受限制的 8 个字符的密码,您的计算是正确的;但是通过答案中的解释,添加的约束实际上使它更有趣,并且更具说明性。
    • @tripleee 这个答案中的约束正好是“36”——a-z 和 0-9。另外:您在自相矛盾-起初您承认我计算了那个约束,然后您立即声称它是“不受约束的”。也许你感到困惑?
    • 限制是前两个是小写字母(字母是 26 个字符),接下来的两个是数字(字母是 10 个字符)等。我不知道我怎么能做到这一点比现在更清晰。
    • 嘘。 在这些约束下。 00000000 违反了约束。在前两个字母的组中,它们是随机、统一和独立选择的。然后从数字池中随机、均匀、独立地抽取两个数字。
    【解决方案2】:

    Shannon's entropy equation 是标准的计算方法。这是一个简单的 Python 实现,无耻地从Revelation 代码库复制而来,因此获得了 GPL 许可:

    import math
    
    
    def entropy(string):
        "Calculates the Shannon entropy of a string"
    
        # get probability of chars in string
        prob = [ float(string.count(c)) / len(string) for c in dict.fromkeys(list(string)) ]
    
        # calculate the entropy
        entropy = - sum([ p * math.log(p) / math.log(2.0) for p in prob ])
    
        return entropy
    
    
    def entropy_ideal(length):
        "Calculates the ideal Shannon entropy of a string with given length"
    
        prob = 1.0 / length
    
        return -1.0 * length * prob * math.log(prob) / math.log(2.0)
    
    

    请注意,此实现假定您的输入比特流最好以字节表示。您的问题域可能会或可能不会出现这种情况。你真正想要的是你的比特流转换成一串数字。您如何决定这些数字是特定领域的。如果您的数字真的只是一和零,那么将您的比特流转换为一和零的数组。但是,您选择的转换方法会影响您获得的结果。

    【讨论】:

    • 啊,谢谢!但这需要您知道位串中的字长?例如,如果我假设这些确实是 2040 字节,我可以将其应用于我的 16,320 位字符串。
    • 编辑答案以提供相关信息
    • 如果只转换为 1 和 0,那么该算法不会将“0101010101...”视为具有最大可能熵吗?
    • 根据密码朋克的回答,这假设了一个模型,其中每个字符在每个位置的可能性都相同。
    • @fmark @dreeves 信息熵取决于可用状态的数量。由于二进制字符串只有 2 种可能的状态,因此最大熵始终为 1。
    【解决方案3】:

    我相信答案是字符串的Kolmogorov Complexity。 这不仅不能用一大块伪代码来回答,Kolmogorov 的复杂性也不是computable function

    您可以在实践中做的一件事是使用可用的最佳data compression 算法压缩位串。 压缩得越多,熵就越低。

    【讨论】:

    • 一个小的修正,低压缩表示低熵,因为低熵等于低无序。 Entropy, Compression, and Information Content
    • “根据这些直觉,Shannon 开发了一种语言的熵测量方法,将高熵分配给无序、随机的第一句,而将低熵分配给有序、有图案的第二句”……来自您的引用论文@isalamon
    • @lsalamon,链接已损坏。
    • @ValmikyArquissandas,这里是另一篇关于Entropy的论文
    • @lsalamon 高压缩 => 低熵。低压缩 => 高熵。
    【解决方案4】:

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

    您的问题是,您试图测量熵以帮助您找到模型,这是不可能的;熵测量可以告诉您模型有多好。

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

    【讨论】:

    • 我不确定我是否理解您的第二段。
    【解决方案5】:

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

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

    更详尽的解释可从本页的PDF 获得:

    http://csrc.nist.gov/groups/ST/toolkit/rng/documentation_software.html

    【讨论】:

    【解决方案6】:

    这是 Python 中的一个实现(我也将它添加到了 Wiki 页面):

    import numpy as np
    
    def ApEn(U, m, r):
    
        def _maxdist(x_i, x_j):
            return max([abs(ua - va) for ua, va in zip(x_i, x_j)])
    
        def _phi(m):
            x = [[U[j] for j in range(i, i + m - 1 + 1)] for i in range(N - m + 1)]
            C = [len([1 for x_j in x if _maxdist(x_i, x_j) <= r]) / (N - m + 1.0) for x_i in x]
            return -(N - m + 1.0)**(-1) * sum(np.log(C))
    
        N = len(U)
    
        return _phi(m) - _phi(m + 1)
    

    示例:

    >>> U = np.array([85, 80, 89] * 17)
    >>> ApEn(U, 2, 3)
    -1.0996541105257052e-05
    

    以上例子与the example given on Wikipedia一致。

    【讨论】:

    • 什么是 m 和 r?
    • 我还有一个问题。使用这个函数,我会得到 0 for randU = np.random.choice([0, 1], size=17 * 3), m = 2, r = 3。这正常吗?
    • @Shabnam 老实说我不记得了,我有一段时间没用过这个了。但是当我编写它时,我非常彻底地测试了我的实现。如果您查看维基百科的文章,我相信您可以理解。
    【解决方案7】:

    通过这个公式使用单词的香农熵:http://imgur.com/a/DpcIH

    这是一个计算它的 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()))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-17
      • 1970-01-01
      • 2010-11-02
      • 2022-04-22
      • 2015-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多