init: v1.0.0
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
package entropy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
func MarkovTests(data []byte, verbose bool) float64 {
|
||||
// 将data转换为0,1比特串表示
|
||||
epsilon := make([]byte, 0, len(data)*8)
|
||||
for _, b := range data {
|
||||
epsilon = append(epsilon, (b>>7)&1)
|
||||
epsilon = append(epsilon, (b>>6)&1)
|
||||
epsilon = append(epsilon, (b>>5)&1)
|
||||
epsilon = append(epsilon, (b>>4)&1)
|
||||
epsilon = append(epsilon, (b>>3)&1)
|
||||
epsilon = append(epsilon, (b>>2)&1)
|
||||
epsilon = append(epsilon, (b>>1)&1)
|
||||
epsilon = append(epsilon, (b>>0)&1)
|
||||
}
|
||||
|
||||
// double markov_test(byte* data, long len, const int verbose, const char *label){
|
||||
var i, C_0, C_1, C_00, C_10 int64
|
||||
var H_min, tmp_min_entropy, P_0, P_1, P_00, P_01, P_10, P_11, entEst float64
|
||||
|
||||
C_0 = 0
|
||||
C_00 = 0
|
||||
C_10 = 0
|
||||
dataLen := int64(len(epsilon))
|
||||
// get counts for unconditional and transition probabilities
|
||||
for i = 0; i < dataLen-1; i++ {
|
||||
if epsilon[i] == 0 {
|
||||
C_0++
|
||||
if epsilon[i+1] == 0 {
|
||||
C_00++
|
||||
}
|
||||
} else if epsilon[i+1] == 0 {
|
||||
C_10++
|
||||
}
|
||||
}
|
||||
|
||||
//C_0 is now the number of 0 bits from S[0] to S[len-2]
|
||||
|
||||
C_1 = dataLen - 1 - C_0 //C_1 is the number of 1 bits from S[0] to S[len-2]
|
||||
|
||||
//Note that P_X1 = C_X1 / C_X = (C_X - C_X0)/C_X = 1.0 - C_X0/C_X = 1.0 - P_X0
|
||||
if C_0 > 0 {
|
||||
P_00 = float64(C_00) / float64(C_0)
|
||||
P_01 = 1.0 - P_00
|
||||
} else {
|
||||
P_00 = 0.0
|
||||
P_01 = 0.0
|
||||
}
|
||||
|
||||
if C_1 > 0 {
|
||||
P_10 = float64(C_10) / float64(C_1)
|
||||
P_11 = 1.0 - P_10
|
||||
} else {
|
||||
P_10 = 0.0
|
||||
P_11 = 0.0
|
||||
}
|
||||
|
||||
// account for the last symbol
|
||||
if epsilon[dataLen-1] == 0 {
|
||||
C_0++
|
||||
}
|
||||
//C_0 is now the number of 0 bits from S[0] to S[len-1]
|
||||
|
||||
P_0 = float64(C_0) / float64(dataLen)
|
||||
P_1 = 1.0 - P_0
|
||||
|
||||
if verbose {
|
||||
fmt.Printf("P_0 = %.17g\n", P_0)
|
||||
fmt.Printf("P_1 = %.17g\n", P_1)
|
||||
fmt.Printf("P_{0,0} = %.17g\n", P_00)
|
||||
fmt.Printf("P_{0,1} = %.17g\n", P_01)
|
||||
fmt.Printf("P_{1,0} = %.17g\n", P_10)
|
||||
fmt.Printf("P_{1,1} = %.17g\n", P_11)
|
||||
}
|
||||
|
||||
H_min = 128.0
|
||||
|
||||
//In the next block, note that if P_0X > 0.0, then P_0 > 0.0
|
||||
//and similarly if P_1X > 0.0, then P_1 > 0.0
|
||||
|
||||
// Sequence 00...0
|
||||
if P_00 > 0.0 {
|
||||
tmp_min_entropy = -math.Log2(P_0) - 127.0*math.Log2(P_00)
|
||||
if tmp_min_entropy < H_min {
|
||||
H_min = tmp_min_entropy
|
||||
}
|
||||
}
|
||||
|
||||
// Sequence 0101...01
|
||||
if (P_01 > 0.0) && (P_10 > 0.0) {
|
||||
tmp_min_entropy = -math.Log2(P_0) - 64.0*math.Log2(P_01) - 63.0*math.Log2(P_10)
|
||||
if tmp_min_entropy < H_min {
|
||||
H_min = tmp_min_entropy
|
||||
}
|
||||
}
|
||||
|
||||
// Sequence 011...1
|
||||
if (P_01 > 0.0) && (P_11 > 0.0) {
|
||||
tmp_min_entropy = -math.Log2(P_0) - math.Log2(P_01) - 126.0*math.Log2(P_11)
|
||||
if tmp_min_entropy < H_min {
|
||||
H_min = tmp_min_entropy
|
||||
}
|
||||
}
|
||||
|
||||
// Sequence 100...0
|
||||
if (P_10 > 0.0) && (P_00 > 0.0) {
|
||||
tmp_min_entropy = -math.Log2(P_1) - math.Log2(P_10) - 126.0*math.Log2(P_00)
|
||||
if tmp_min_entropy < H_min {
|
||||
H_min = tmp_min_entropy
|
||||
}
|
||||
}
|
||||
|
||||
// Sequence 1010...10
|
||||
if (P_10 > 0.0) && (P_01 > 0.0) {
|
||||
tmp_min_entropy = -math.Log2(P_1) - 64.0*math.Log2(P_10) - 63.0*math.Log2(P_01)
|
||||
if tmp_min_entropy < H_min {
|
||||
H_min = tmp_min_entropy
|
||||
}
|
||||
}
|
||||
|
||||
// Sequence 11...1
|
||||
if P_11 > 0.0 {
|
||||
tmp_min_entropy = -math.Log2(P_1) - 127.0*math.Log2(P_11)
|
||||
if tmp_min_entropy < H_min {
|
||||
H_min = tmp_min_entropy
|
||||
}
|
||||
}
|
||||
|
||||
entEst = math.Min(H_min/128.0, 1.0)
|
||||
|
||||
if verbose {
|
||||
fmt.Printf("p_max = %.17g\n", math.Pow(2.0, -H_min))
|
||||
fmt.Printf("min entropy = %.17g\n", entEst)
|
||||
}
|
||||
|
||||
return entEst
|
||||
}
|
||||
Reference in New Issue
Block a user