File: math.cpp

package info (click to toggle)
entropybroker 2.9-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,600 kB
  • sloc: cpp: 14,386; sh: 934; makefile: 188; java: 148; perl: 12
file content (89 lines) | stat: -rw-r--r-- 2,111 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <string>
#include <vector>
#include <zlib.h>

#include "error.h"
#include "log.h"
#include "utils.h"
#include "math.h"

bit_count_estimator::bit_count_estimator(const bit_count_estimator_type_t type_in) : type(type_in)
{
}

int bit_count_estimator::get_bit_count(const unsigned char *const data, const unsigned int n_bytes)
{
	if (n_bytes == 0)
		return 0;

#ifdef _DEBUG
	int sh = determine_number_of_bits_of_data_shannon(data, n_bytes);
	int compr = determine_number_of_bits_of_data_compression(data, n_bytes);
	dolog(LOG_DEBUG, "in: %d, shannon: %d, compression: %d", n_bytes * 8, sh, compr);

	if (type == BCE_SHANNON)
		return sh;
	else if (type == BCE_COMPRESSION)
		return compr;
#else
	if (type == BCE_SHANNON)
		return determine_number_of_bits_of_data_shannon(data, n_bytes);
	else if (type == BCE_COMPRESSION)
		return determine_number_of_bits_of_data_compression(data, n_bytes);
#endif

	error_exit("Bit count estimator: unknown mode");

	return -1;
}

int bit_count_estimator::determine_number_of_bits_of_data_shannon(const unsigned char *const data, const unsigned int n_bytes)
{
	double ent = 0.0, nbytesd = double(n_bytes);

	int cnts[256];
	memset(cnts, 0x00, sizeof cnts);

	for(unsigned int loop=0; loop<n_bytes; loop++)
		cnts[data[loop]]++;

	for(unsigned int loop=0; loop<256; loop++)
	{
		if (cnts[loop])
		{
			double prob = double(cnts[loop]) / nbytesd;

			ent += prob * log2(1.0 / prob);
		}
	}

	ent *= nbytesd;

	if (ent < 0.0)
		ent=0.0;

	ent = std::min(nbytesd * 8.0, ent);

	return ent;
}

int bit_count_estimator::determine_number_of_bits_of_data_compression(const unsigned char *const data, const unsigned int n_bytes)
{
	uLongf destLen = n_bytes * 2 + 512;
	unsigned char *dest = new unsigned char[destLen];

	int rc = -1;
	if ((rc = compress2(dest, &destLen, data, n_bytes, 9)) != Z_OK)
		error_exit("Failed invoking zlib %d", rc);

	delete [] dest;

	// zlib adds a 6 byte header
	double factor = double(destLen - 6) / double(n_bytes);

	return int(factor * double(n_bytes) * 8.0);
}