问题描述
我有不同的文件类型,包括JPEG和jpg,#mp3,#GIF,#MP4,#FLV,M4V,exe,zip等。
如上所述,我们如何才能找到不同类型文件的熵,以及如何将每个文件的分数定为0到1。
解决方法
+1一个非常有趣的问题,这里有一些未经检验的想法,只是从现在开始我就想到了:
-
具有相同大小(4K)的均匀随机数据?或先使用 FFT ,然后进行关联...
-
或计算统计属性并以某种方式从中推断...
我知道这是模糊的描述,但可能值得深入探讨...
-
使用约束
例如,用Huffman coding压缩4K数据,并根据未压缩大小与压缩大小之间的比率推断系数,并且可以使用对数刻度...
我认为最容易实现和合理的结果将来自第三种方法,因为Huffman coding
和熵密切相关。
[edit1]使用Shannon信息熵
您的建议甚至比Hufman编码更好(即使那两个是紧密相关的)。使用Shannon information entropy H
(以二进制数字为基数)将返回表示数据所需的每个数据字的平均位数(经过Hufman编码后)。所以从那里开始<0..1>
的得分只是每个单词的位数...
以下是在BYTE上进行熵计算的小型C ++ / VCL示例:
//$$---- Form CPP ----
//---------------------------------------------------------------------------
#include <vcl.h>
#include <math.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
char txt0[]="text Text bla bla bla ...";
char txt1[]="abcdefghijklmnopqrstuvwxy";
char txt2[]="AAAAAAAbbbbbccccddddeeeff";
//---------------------------------------------------------------------------
double entropy(BYTE *dat,int siz)
{
if ((siz<=0)||(dat==NULL)) return 0.0;
int i; double H=0.0,P[256],dp=1.0/siz,base=1.0/log(2.0);
for (i=0;i<256;i++) P[i]=0.0;
for (i=0;i<siz;i++) P[dat[i]]+=dp;
for (i=0;i<256;i++)
{
if (P[i]==0.0) continue; // skip non existing items
if (P[i]==1.0) return 0.0; // this means only 1 item type is present in data
H-=P[i]*log(P[i])*base; // shanon entropy (binary bits base)
}
return H;
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner)
{
mm_log->Lines->Clear();
mm_log->Lines->Add(AnsiString().sprintf("txt = \"%s\",H = %.6lf,H/8 = %.6lf",txt0,entropy(txt0,sizeof(txt0)),sizeof(txt0))/8.0));
mm_log->Lines->Add(AnsiString().sprintf("txt = \"%s\",txt1,entropy(txt1,sizeof(txt1)),sizeof(txt1))/8.0));
mm_log->Lines->Add(AnsiString().sprintf("txt = \"%s\",txt2,entropy(txt2,sizeof(txt2)),sizeof(txt2))/8.0));
}
//-------------------------------------------------------------------------
结果:
txt = "text Text bla bla bla ...",H = 3.185667,H/8 = 0.398208
txt = "abcdefghijklmnopqrstuvwxy",H = 4.700440,H/8 = 0.587555
txt = "AAAAAAAbbbbbccccddddeeeff",H = 2.622901,H/8 = 0.327863