-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathnist.cpp
More file actions
127 lines (103 loc) · 3.73 KB
/
nist.cpp
File metadata and controls
127 lines (103 loc) · 3.73 KB
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <shared/utils.h>
#define NO_NIST_DEFS
#include "nist.hpp"
Stats::Stats(data_t &data) {
calc_stats(&data, this->rawmean, this->median);
}
#include <shared/most_common.h>
#include <shared/lrs_test.h>
#include <iid/permutation_tests.h>
#include <iid/chi_square_tests.h>
#include <non_iid/collision_test.h>
#include <non_iid/lz78y_test.h>
#include <non_iid/multi_mmc_test.h>
#include <non_iid/lag_test.h>
#include <non_iid/multi_mcw_test.h>
#include <non_iid/compression_test.h>
#include <non_iid/markov_test.h>
#include <omp.h>
#include <limits.h>
data_t construct_data_t(
const char *symbols,
unsigned long symbols_len,
int bits_per_word
) {
if (symbols_len == 0)
throw std::invalid_argument("Need more than zero symbols!");
data_t data;
////////////////////////////////////////////////////
// init symbols
data.len = symbols_len;
data.symbols = (byte*) malloc(data.len);
if (data.symbols == NULL) {
free_data(&data);
throw std::runtime_error("Failure to initialize memory for symbols!");
}
memcpy(data.symbols, symbols, data.len);
////////////////////////////////////////////////////
// init wordsize
data.word_size = bits_per_word;
// check bits per word with the actual symbols
byte datamask = 0;
byte curbit = 0x80;
for(int i = 0; i < data.len; i++) {
datamask = datamask | data.symbols[i];
}
int calculated_wordsize;
for(calculated_wordsize=8; (calculated_wordsize>0) && ((datamask & curbit) == 0); calculated_wordsize--) {
curbit = curbit >> 1;
}
if( calculated_wordsize < data.word_size ) {
printf("Warning: Symbols appear to be narrower than described.\n");
} else if( calculated_wordsize > data.word_size ) {
free_data(&data);
throw std::invalid_argument("Incorrect bit width specification: Data does not fit within described bit width.\n");
}
////////////////////////////////////////////////////
// init rawsymbols
data.rawsymbols = (byte*) malloc(data.len);
if(data.rawsymbols == NULL){
free_data(&data);
throw std::runtime_error("Failure to initialize memory for rawsymbols!");
}
memcpy(data.rawsymbols, data.symbols, data.len);
////////////////////////////////////////////////////
// init max symbols and create symbol map down table
data.maxsymbol = 0;
int max_symbols = 1 << data.word_size;
int symbol_map_down_table[max_symbols];
// create symbols (samples) and check if they need to be mapped down
data.alph_size = 0;
memset(symbol_map_down_table, 0, max_symbols*sizeof(int));
int mask = max_symbols-1;
for(int i = 0; i < data.len; i++){
data.symbols[i] &= mask;
if(data.symbols[i] > data.maxsymbol) data.maxsymbol = data.symbols[i];
if(symbol_map_down_table[data.symbols[i]] == 0) symbol_map_down_table[data.symbols[i]] = 1;
}
for(int i = 0; i < max_symbols; i++){
if(symbol_map_down_table[i] != 0) symbol_map_down_table[i] = (byte)data.alph_size++;
}
////////////////////////////////////////////////////
// create bsymbols (bitstring) using the non-mapped data
data.blen = data.len * data.word_size;
if(data.word_size == 1) data.bsymbols = data.symbols;
else{
data.bsymbols = (byte*)malloc(data.blen);
if(data.bsymbols == NULL){
throw std::runtime_error("failure to initialize memory for bsymbols!");
free_data(&data);
}
for(int i = 0; i < data.len; i++){
for(int j = 0; j < data.word_size; j++){
data.bsymbols[i*data.word_size+j] = (data.symbols[i] >> (data.word_size-1-j)) & 0x1;
}
}
}
////////////////////////////////////////////////////
// map down symbols if less than 2^bits_per_word unique symbols
if(data.alph_size < data.maxsymbol + 1){
for(int i = 0; i < data.len; i++) data.symbols[i] = (byte)symbol_map_down_table[data.symbols[i]];
}
return data;
}