获取大文件的熵
本文关键字:文件 获取 | 更新日期: 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;
}
这不是
一个完整的答案。完成的速度取决于文件中的位数或字符数(每个位都有助于熵的度量)。您可以使用某些压缩算法来测量熵的文件压缩程度 - 因此,如果它没有压缩太多,则内容具有高熵等。我希望这有所帮助。