获取大文件的熵

本文关键字:文件 获取 | 更新日期: 2023-09-27 18:32:20

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

获取大文件的熵

它看起来像这样。

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()并用char替换byte来计算字符熵而不是字节熵。 我怀疑你会使用 Linq 找到更快的解决方案,但尝试会成为一个很好的难题。

按照本页其他地方的要求,这里是piedar答案的unsafe版本。我下面的版本还包含以下更改:

  • 将对数更正为底数为2(而不是256),以与香农的熵公式一致,熵是描述系统状态所需的最小位数。事实上,调用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)。这个法令,虽然没有明显的辩护,但d̲o̲e̲s̲有效地将单一的可疑案例与信息量更大的0.000结果(如Entropy(new byte[] { 123 })Entropy(new byte[] { 0xff, 0xff, 0xff })等)区分开来。
  • 已删除特定的文件读取行为,以便以下函数适用于任何类型的数据信息
  • 承认香农的开创性贡献,将变量名称更改为"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;
}
这不是

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