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 }