如何计算位串的近似熵?

时间:2010-06-05 04:35:51

标签: encryption entropy information-theory data-compression

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

谷歌搜索 - "approximate entropy" bits - 揭示多篇学术论文,但我想找到一个伪代码块来定义任意长度的给定位串的近似熵。

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

另见相关问题:
What is the computer science definition of entropy?

8 个答案:

答案 0 :(得分:30)

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

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

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

答案 1 :(得分:19)

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)

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

答案 2 :(得分:10)

我相信答案是字符串的Kolmogorov Complexity。 这不仅对一大块伪代码负责,Kolmogorov复杂性不是computable function

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

答案 3 :(得分:9)

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

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

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

答案 4 :(得分:6)

很抱歉这么久回答这个问题。

看看我最近的论文:

“BiEntropy - 有限二进制字符串的近似熵”

http://arxiv.org/abs/1305.0954

“我们设计,实现并测试了一个简单的算法,该算法计算任意长度的有限二进制串的近似熵。该算法使用字符串的Shannon Entropies的加权平均值以及字符串的最后二进制导数我们在素数理论(我们明确证明素数序列不是周期性的),人类视觉,密码学,随机数生成和定量金融领域成功地测试了算法“

答案 5 :(得分:4)

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

  

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

此页面上的PDF提供了更全面的解释:

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

答案 6 :(得分:1)

这是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一致。

答案 7 :(得分:0)

使用具有以下公式的单词的香农熵: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()))