计算不同文件扩展名的熵以发现数据的随机性?
Compute entropy of different file extensions to find randomness of data?
我有不同的文件类型,包括 JPEG 和 jpg、#mp3、#GIF、#MP4、#FLV、M4V、exe、zip 等
以块为单位获取数据,大约 4k 块大小,寻找随机性
生成介于 0 和 1 之间的随机分数
尽量按随机分数类放
我们如何找到上述不同类型文件的熵,我们能否在 0 和 1 之间缩放每个文件分数。
+1 个非常有趣的问题,现在我的脑海中浮现出一些未经检验的想法:
- 怎么样
具有相同大小 (4K) 的均匀随机数据?和/或先使用 FFT 然后关联 ...
或者计算统计属性并从那里以某种方式推断...
我知道这是模糊的描述,但可能值得深入研究...
使用压缩
例如用 Huffman coding 压缩您的 4K 数据并推断您的系数形成未压缩和压缩大小之间的比率,并且可以使用对数标度 ...
我认为最容易实现和合理的结果将来自第三种方法,因为Huffman coding
和熵密切相关。
[edit1] 使用香农信息熵
你的建议甚至比 Hufman 编码更好(即使这 2 个是密切相关的)。使用 Shannon information entropy H
和二进制数字作为基数将 return 表示数据所需的每个数据字的平均位数(经过 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)),entropy(txt0,sizeof(txt0))/8.0));
mm_log->Lines->Add(AnsiString().sprintf("txt = \"%s\" , H = %.6lf , H/8 = %.6lf",txt1,entropy(txt1,sizeof(txt1)),entropy(txt1,sizeof(txt1))/8.0));
mm_log->Lines->Add(AnsiString().sprintf("txt = \"%s\" , H = %.6lf , H/8 = %.6lf",txt2,entropy(txt2,sizeof(txt2)),entropy(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
我有不同的文件类型,包括 JPEG 和 jpg、#mp3、#GIF、#MP4、#FLV、M4V、exe、zip 等
以块为单位获取数据,大约 4k 块大小,寻找随机性
生成介于 0 和 1 之间的随机分数
尽量按随机分数类放
我们如何找到上述不同类型文件的熵,我们能否在 0 和 1 之间缩放每个文件分数。
+1 个非常有趣的问题,现在我的脑海中浮现出一些未经检验的想法:
- 怎么样
具有相同大小 (4K) 的均匀随机数据?和/或先使用 FFT 然后关联 ...
或者计算统计属性并从那里以某种方式推断...
我知道这是模糊的描述,但可能值得深入研究...
使用压缩
例如用 Huffman coding 压缩您的 4K 数据并推断您的系数形成未压缩和压缩大小之间的比率,并且可以使用对数标度 ...
我认为最容易实现和合理的结果将来自第三种方法,因为Huffman coding
和熵密切相关。
[edit1] 使用香农信息熵
你的建议甚至比 Hufman 编码更好(即使这 2 个是密切相关的)。使用 Shannon information entropy H
和二进制数字作为基数将 return 表示数据所需的每个数据字的平均位数(经过 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)),entropy(txt0,sizeof(txt0))/8.0));
mm_log->Lines->Add(AnsiString().sprintf("txt = \"%s\" , H = %.6lf , H/8 = %.6lf",txt1,entropy(txt1,sizeof(txt1)),entropy(txt1,sizeof(txt1))/8.0));
mm_log->Lines->Add(AnsiString().sprintf("txt = \"%s\" , H = %.6lf , H/8 = %.6lf",txt2,entropy(txt2,sizeof(txt2)),entropy(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