在浏览了与文件熵相关的所有帖子之后,出现了获取大文件熵的问题。我的意思是它可以多快地完成,并且算法可以解决这个问题。有可能以某种方式使用LINQ,如果是这样,解决方案的速度有多快?谢谢大家的进步。
答案 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 answer的unsafe
版本。我的以下版本还包含以下更改:
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 })
,和其他人。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)
这不是一个完整的答案。 它的完成速度取决于文件中位数或字符数的时间比例(每一位都有助于测量熵)。 你可以使用一些压缩算法来测量文件压缩的程度来测量熵 - 所以如果它没有压缩太多,那么内容具有高熵等等。我希望有所帮助。