1 package org.jastacry.test.utils;
2
3 import java.util.ArrayList;
4
5 /**
6 * Helper functions for checking entropy.
7 *
8 */
9 public final class ShannonEntropy
10 {
11 private double entropy = 0.0;
12
13 public double getEntropy()
14 {
15 return entropy;
16 }
17
18 /**
19 * Constructor of class.
20 */
21 public ShannonEntropy()
22 {
23 entropy = 0.0;
24 }
25
26 /**
27 * Calculate entropy.
28 *
29 * @param in
30 * String to analyze
31 */
32 public void calculate(final String in)
33 {
34 byte[] bArray = in.getBytes();
35 calculate(bArray);
36 } // function
37
38 /**
39 * Calculate entropy.
40 *
41 * @param bArray
42 * byte array to analyze
43 */
44 public void calculate(final byte[] bArray)
45 {
46 entropy = 0.0;
47 ArrayList<ByteFreq> freqs = new ArrayList<>();
48 for (int i = 0; i < bArray.length; i++)
49 {
50 byte b = bArray[i];
51 boolean flag = true;
52 for (ByteFreq cf : freqs)
53 {
54 if (cf.byteValue == b)
55 {
56 flag = false;
57 cf.count++;
58 break;
59 } // if
60 flag = true;
61 } // for
62 if (flag)
63 {
64 freqs.add(new ByteFreq(b));
65 } // if
66 } // for
67
68 for (ByteFreq cf : freqs)
69 {
70 int freq = cf.count;
71 if (freq == 0)
72 {
73 continue;
74 } // if
75
76 double c = (double) freq / bArray.length;
77 entropy -= log2(Math.pow(c, c));
78 } // for
79 } // function
80
81 /**
82 * Implement log2 function.
83 * @param x input value
84 * @return log2 of input value
85 */
86 private double log2(final double x)
87 {
88 return Math.log(x) / Math.log(2);
89 } // math function
90
91 @Override
92 public String toString()
93 {
94 return "Entropy: " + this.entropy;
95 } // function
96
97 /**
98 * inner class for array use.
99 *
100 */
101 class ByteFreq
102 {
103 public final byte byteValue;
104 public int count = 1;
105
106 /**
107 * inner constructor.
108 *
109 * @param in
110 * byte to count
111 */
112 public ByteFreq(byte in)
113 {
114 this.byteValue = in;
115 } // constructor
116
117 } // inner class
118
119 } // class ShannonEntropy