获取大文件的熵

时间:2016-01-29 05:24:58

标签: c#

在浏览了与文件熵相关的所有帖子之后,出现了获取大文件熵的问题。我的意思是它可以多快地完成,并且算法可以解决这个问题。有可能以某种方式使用LINQ,如果是这样,解决方案的速度有多快?谢谢大家的进步。

3 个答案:

答案 0 :(得分:1)

它看起来像这样。

static double CalculateEntropy(FileInfo file)
{
    int range = byte.MaxValue + 1; // 0 -> 256
    byte[] values = File.ReadAllBytes(file.FullName);

    long[] counts = new long[range];
    foreach (byte value in values)
    {
        counts[value]++;
    }

    double entropy = 0;
    foreach (long count in counts)
    {
        if (count != 0)
        {
            double probability = (double)count / values.LongLength;
            entropy -= probability * Math.Log(probability, range);
        }
    }
    return entropy;
}

您可以通过交换File.ReadAllText()并将byte替换为char来计算字符熵而不是字节熵。我怀疑你会找到一个使用Linq的更快的解决方案,但尝试会成为一个很好的难题。

答案 1 :(得分:1)

根据本页其他地方的要求,此处为piedar's answerunsafe版本。我的以下版本还包含以下更改:

  • 将对数更正为 base 2 (而不是256),以便与Shannon's entropy的公式一致,作为最小位数需要描述系统的状态。确实,现在调用Entropy(new byte[] { 0, 1, 2, ... 255 })会给出预期答案 8.0 Entropy(new byte[] { 88, 79, 79, 88 })返回 1.0 Entropy(new byte[] { 4, 15, 20, 166 })返回 2.0 等等。
  • 通过从循环中提取分母来提高浮点精度以减少下溢。
  • 循环提取还需要退化Entropy(new byte[0]) - 即,什么都没有熵 - 现在返回NaN(而不是0.000)。这个法令虽然not overtly defensible 有用地区分单个可疑案例和更强信息 0.000 结果,例如Entropy(new byte[] { 123 })Entropy(new byte[] { 0xff, 0xff, 0xff }),和其他人。
  • 已删除特定的文件阅读行为,以便下面的函数适用于任何类型的数据 information
  • 承认Shannon的开创性贡献,将变量名称更改为“H”。

public static unsafe Double Entropy(byte[] data)
{
    int* rgi = stackalloc int[0x100], pi = rgi + 0x100;

    for (int i = data.Length; --i >= 0;)
        rgi[data[i]]++;

    Double H = 0.0, cb = data.Length;
    while (--pi >= rgi)
        if (*pi > 0)
            H += *pi * Math.Log(*pi / cb, 2.0);

    return -H / cb;
}

答案 2 :(得分:0)

这不是一个完整的答案。 它的完成速度取决于文件中位数或字符数的时间比例(每一位都有助于测量熵)。 你可以使用一些压缩算法来测量文件压缩的​​程度来测量熵 - 所以如果它没有压缩太多,那么内容具有高熵等等。我希望有所帮助。