資訊熵很有用,就拿我的老本行反病毒來說,它是靜態病毒特徵的常見組成部分。資訊熵的計算公式很簡單:
$ entropy=-\sum_^p(x_)log_p(x_) $
其中,$ p(x_) $是隨機變數$x_$出現的概率,這裡熵的單位是bit。通常,我們用$c(x_)$表示$x_$出現的次數,$t=\sum_^c(x_)$表示觀察次數的總和,那麼:
$ entropy=-\sum_^\frac)}log_\frac)} $
根據這個公式,最直接也是最常見的求熵程式類似於:
double entropy(int *counts, int n, inttotal)
}return sum / log(2.0
);}
比如,要計算某段記憶體資料的熵,一般是這樣呼叫entropy函式的:
double entropy_data(unsigned char *data, intsize)
如果記憶體資料裡的位元組是均勻分布的(比如隨機位元組序列),那麼熵值接近於8。反之,某幾個位元組大量重複出現時,熵值接近於0。在病毒特徵中,特定檔案資料的熵值是判斷檔案是否經過壓縮加密的重要指標。
在實際應用中,我們對熵的精度要求並不高,15個有效位的double乃至7個有效位的float都顯得有些「浪費」,而浮點運算又使得熵的計算速度不敢恭維。那麼,是否可以在犧牲部分精度的前提下,快速計算近似熵值呢?答案是肯定的。經過幾天的琢磨,終於寫了乙個出來。
在貼出**之前,先看一下計算100萬次熵值的用時對比資料(單位:ms)。測試環境:i7-3520m @2.9ghz, 8gb ram, win7 sp1 64-bit。
x86 編譯
x64 編譯
entropy
4575.6
9851.5
fast_entropy
677.1
405.6
x86版本的fast_entropy速度大約是entropy的6倍,x64版本的fast_entropy速度是entropy的24倍。結果精度方面,fast_entropy一般可以精確至小數點後3到4位,嚴格的誤差分析還沒有做,有時間會補上。
fast_entropy用了整數運算來替代浮點運算,並應用了ieee浮點數儲存格式的技巧,得以用整數運算近似log運算。之所以在x64下表現更好,是因為64-bit整數操作在x64上更快。
好了,上**!
staticint _u[256] =;
static inline long
long _lxlogx(int
x)double fast_entropy(int *counts, int n, int
total)
s +=_lxlogx(total);
s /=total;
return
0.00000011920929 *s;
}
樣本熵的matlab程式
matlab下的動態樣本熵計算 sampen 計算時間序列data的樣本熵 data為輸入資料序列 m為初始分段,每段的資料長度 r為閾值 author lskyp date 2010.6.20 orig version v1.0 分開計算長度為m的序列和長度為m 1的序列 這一版的計算有些問題,需...
matlab練習程式(Renyi熵)
renyi熵是對通常的夏農熵的擴充套件,算是q階廣義熵。公式如下 其中p和夏農熵公式中的p一樣,是概率。當q 1時公式退化為夏農熵公式。如何證明?看wiki吧 有用此公式尋找影象 最佳二值化閾值的。首先定義前景區域a,背景區域b。那麼前景與背景區域畫素相應的renyi熵就如下定義 其中k是當前取的灰...
乙個快速法求素數的程式
閒暇時寫了乙個找出小於某個數字的素數的程式。最常見的方法是篩選法吧。原理大致如下 若要求得16以內的所有素數,1 在陣列中存放一下資料 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 2 先篩選掉是2的倍數 2 3 4 5 6 7 8 9 10 11 12 13 14 15...