Ultima attività 1 month ago

LRIT Packet Decoder

Revisione a8ba4344bb743ae1ecfdc9f3da6d0f7ece8b1703

decoder.c Raw
1#include <stdio.h>
2#include <stdint.h>
3#include <stdlib.h>
4#include <unistd.h>
5#include <time.h>
6#include <math.h>
7#include <memory.h>
8#include <limits.h>
9#include <sys/time.h>
10#include <sys/resource.h>
11#include <fec.h>
12#include "random/pn.h"
13
14static const unsigned char BitsSetTable256[256] = {
15# define B2(n) n, n+1, n+1, n+2
16# define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2)
17# define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2)
18 B6(0), B6(1), B6(1), B6(2)
19};
20
21// Header, because I don't want an extra file
22
23#define FRAMESIZE 1024
24#define SYNCWORDSIZE 32
25#define MINCORRELATIONBITS 46
26#define FRAMEBITS (FRAMESIZE * 8)
27
28#define VITPOLYA 0x4F
29#define VITPOLYB 0x6D
30
31#define CHECK_VITERBI_CORRECTIONS
32
33#define CODEDFRAMESIZE (FRAMEBITS * 2)
34#define SYNCWORDSIZEDOUBLE (SYNCWORDSIZE * 2)
35#define PARITY_OFFSET 892
36
37const uint64_t UW0 = 0xfca2b63db00d9794;
38const uint64_t UW2 = 0x035d49c24ff2686b;
39const uint64_t REVUW0 = 0xfc51793e700e6b68;
40const uint64_t REVUW2 = 0x03ae86c18ff19497;
41
42typedef struct {
43 uint32_t uw0mc;
44 uint32_t uw0p;
45 uint32_t uw2mc;
46 uint32_t uw2p;
47 uint32_t ruw0mc;
48 uint32_t ruw0p;
49 uint32_t ruw2mc;
50 uint32_t ruw2p;
51} correlation_t ;
52
53uint8_t UW0b[SYNCWORDSIZE * 2];
54uint8_t UW2b[SYNCWORDSIZE * 2];
55uint8_t REVUW0b[SYNCWORDSIZE * 2];
56uint8_t REVUW2b[SYNCWORDSIZE * 2];
57
58uint8_t codedData[CODEDFRAMESIZE];
59uint8_t decodedData[FRAMESIZE];
60uint8_t correctedData[CODEDFRAMESIZE];
61uint8_t rsCorrectedData[FRAMESIZE];
62uint8_t rsWorkBuffer[255];
63
64uint8_t M_PDU[886];
65
66int viterbiPolynomial[2] = {VITPOLYA, VITPOLYB};
67
68
69void initUW();
70void checkCorrelation(uint8_t *buffer, int buffLength, correlation_t *corr);
71void resetCorrelation(correlation_t * corr);
72uint32_t hardCorrelate(uint8_t dataByte, uint8_t wordByte);
73void fixPacket(uint8_t *buffer, int buffLength, uint8_t n);
74void convEncode(uint8_t *data, int dataLength, uint8_t *output, int outputLen);
75uint32_t calculateError(uint8_t *original, uint8_t *corrected, int length);
76void deinterleaveRS(uint8_t *data, uint8_t *rsbuff, uint8_t pos, uint8_t I);
77void interleaveRS(uint8_t *idata, uint8_t *outbuff, uint8_t pos, uint8_t I);
78void writeChannel(uint8_t *data, int size, uint16_t vcid);
79// Code
80
81uint32_t swapEndianess(uint32_t num) {
82 return ((num>>24)&0xff) | ((num<<8)&0xff0000) | ((num>>8)&0xff00) | ((num<<24)&0xff000000);
83}
84
85uint32_t maxCorrelation(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
86 uint32_t f = (a > b ? a : b);
87 uint32_t g = (c > d ? c : d);
88 return f > g ? f : g;
89}
90
91
92void initUW() {
93 printf("Converting Sync Words to Soft Data\n");
94 for (int i = 0; i < SYNCWORDSIZEDOUBLE; i++) {
95 UW0b[i] = (UW0 >> (SYNCWORDSIZEDOUBLE-i-1)) & 1 ? 0xFF : 0x00;
96 UW2b[i] = (UW2 >> (SYNCWORDSIZEDOUBLE-i-1)) & 1 ? 0xFF : 0x00;
97 REVUW0b[i] = (REVUW0 >> (SYNCWORDSIZEDOUBLE-i-1)) & 1 ? 0xFF : 0x00;
98 REVUW2b[i] = (REVUW2 >> (SYNCWORDSIZEDOUBLE-i-1)) & 1 ? 0xFF : 0x00;
99 }
100}
101
102uint32_t hardCorrelate(uint8_t dataByte, uint8_t wordByte) {
103 //1 if (a > 127 and b == 255) or (a < 127 and b == 0) else 0
104 return (dataByte >= 127 & wordByte == 0) | (dataByte < 127 & wordByte == 255);
105}
106
107void checkCorrelation(uint8_t *buffer, int buffLength, correlation_t *corr) {
108 resetCorrelation(corr);
109 for (int i = 0; i < buffLength - SYNCWORDSIZEDOUBLE; i++) {
110 uint32_t uw0c = 0;
111 uint32_t uw2c = 0;
112 uint32_t ruw0c = 0;
113 uint32_t ruw2c = 0;
114
115 for (int k = 0; k < SYNCWORDSIZEDOUBLE; k++) {
116 uw0c += hardCorrelate(buffer[i+k], UW0b[k]);
117 uw2c += hardCorrelate(buffer[i+k], UW2b[k]);
118 ruw0c += hardCorrelate(buffer[i+k], REVUW0b[k]);
119 ruw2c += hardCorrelate(buffer[i+k], REVUW2b[k]);
120 }
121
122 corr->uw0p = uw0c > corr->uw0mc ? i : corr->uw0p;
123 corr->uw2p = uw2c > corr->uw2mc ? i : corr->uw2p;
124 corr->ruw0p = ruw0c > corr->ruw0mc ? i : corr->ruw0p;
125 corr->ruw2p = ruw2c > corr->ruw2mc ? i : corr->ruw2p;
126
127 corr->uw0mc = uw0c > corr->uw0mc ? uw0c : corr->uw0mc;
128 corr->uw2mc = uw2c > corr->uw2mc ? uw2c : corr->uw2mc;
129 corr->ruw0mc = ruw0c > corr->ruw0mc ? ruw0c : corr->ruw0mc;
130 corr->ruw2mc = ruw2c > corr->ruw2mc ? ruw2c : corr->ruw2mc;
131 }
132}
133
134void resetCorrelation(correlation_t * corr) {
135 memset(corr, 0x00, sizeof(correlation_t));
136}
137
138void fixPacket(uint8_t *buffer, int buffLength, uint8_t n) {
139 if (n != 0) {
140 for (int i=0; i < buffLength; i+=2) {
141 if (n % 2) { // Process IQ Inversion
142 char a = buffer[i];
143 buffer[i] = buffer[i+1];
144 buffer[i+1] = a;
145 }
146
147 if (n >= 4) { // Process 180 phase shift, aka inverted bits
148 buffer[i] ^= 0xFF;
149 buffer[i+1] ^= 0xFF;
150 }
151 }
152 }
153}
154
155uint32_t calculateError(uint8_t *original, uint8_t *corrected, int length) {
156 uint32_t errors = 0;
157 for (int i=0; i<length; i++) {
158 errors += hardCorrelate(original[i], ~corrected[i]);
159 }
160
161 return errors;
162}
163
164void convEncode(uint8_t *data, int dataLength, uint8_t *output, int outputLen) {
165 unsigned int encstate = 0;
166 uint8_t c;
167 uint32_t pos = 0;
168 uint32_t opos = 0;
169
170 memset(output, 0x00, outputLen);
171 while (pos < dataLength && (pos * 16) < outputLen) {
172 c = data[pos];
173 for(int i=7;i>=0;i--){
174 encstate = (encstate << 1) | ((c >> 7) & 1);
175 c <<= 1;
176 output[opos] = ~(0 - parity(encstate & viterbiPolynomial[0]));
177 output[opos+1] = ~(0 - parity(encstate & viterbiPolynomial[1]));
178
179 opos += 2;
180 }
181 pos++;
182 }
183}
184
185void printBuff(uint8_t *buff, int length) {
186 int countlen = (length > 40 ? 40 : length);
187 for (int i=0; i<countlen; i++) {
188 if (i % 8 == 0 && i != 0) {
189 printf("\n");
190 }
191 printf("%d ", buff[i]);
192 }
193 printf("\n");
194}
195
196void deinterleaveRS(uint8_t *data, uint8_t *rsbuff, uint8_t pos, uint8_t I) {
197 // Copy data
198 for (int i=0; i<223; i++) {
199 rsbuff[i] = data[i*I + pos];
200 }
201 // Copy parity
202 for (int i=0; i<32; i++) {
203 rsbuff[i+223] = data[PARITY_OFFSET + i*I + pos];
204 }
205}
206
207void interleaveRS(uint8_t *idata, uint8_t *outbuff, uint8_t pos, uint8_t I) {
208 // Copy data
209 for (int i=0; i<223; i++) {
210 outbuff[i*I + pos] = idata[i];
211 }
212 // Copy parity - Not needed here, but I do.
213 for (int i=0; i<32; i++) {
214 //outbuff[PARITY_OFFSET + i*I + pos] = idata[i+223];
215 outbuff[PARITY_OFFSET + i*I + pos] = 0x00;
216 }
217}
218
219void writeChannel(uint8_t *data, int size, uint16_t vcid) {
220 char filename[256];
221 sprintf(filename, "channels/channel_%d.bin", vcid);
222 FILE *f = fopen(filename, "a+");
223 fwrite(data, size, 1, f);
224 fclose(f);
225}
226
227int main(int argc,char *argv[]) {
228
229 if (argc < 3) {
230 printf("Usage: ./decoder inputfile outputfile");
231 return 1;
232 }
233
234 char *inputfile = argv[1];
235 char *outputfile = argv[2];
236 void *viterbi;
237
238 correlation_t corr;
239
240 printf("Opening files\n");
241 FILE *input = fopen(inputfile, "r");
242 FILE *output = fopen(outputfile, "w");
243
244 initUW();
245
246 printf("Initializing Viterbi\n");
247 set_viterbi27_polynomial(viterbiPolynomial);
248 if((viterbi = create_viterbi27(FRAMEBITS)) == NULL){
249 printf("create_viterbi27 failed\n");
250 exit(1);
251 }
252
253 fseek(input, 0L, SEEK_END);
254 uint64_t sz = ftell(input);
255 fseek(input, 0L, SEEK_SET);
256 printf("Input size is %lu\n", sz);
257
258 uint64_t readsize = 0;
259 uint64_t frameCount = 1;
260
261 while (readsize < sz) {
262 // Read Data
263 uint32_t chunkSize = sz - readsize > CODEDFRAMESIZE ? CODEDFRAMESIZE : sz - readsize;
264 memset(codedData, 0x00, CODEDFRAMESIZE);
265 fread(codedData, chunkSize, 1, input);
266
267 //printBuff(codedData, chunkSize);
268 // Check Correlation
269 checkCorrelation(codedData, chunkSize, &corr);
270 // Get Max Correlation
271 uint32_t maxCorr = maxCorrelation(corr.uw0mc, corr.uw2mc, corr.ruw0mc, corr.ruw2mc);
272
273 if (maxCorr < MINCORRELATIONBITS) {
274 printf(" Skipping read. Correlation %d less than required %d.\n", maxCorr, MINCORRELATIONBITS);
275 } else {
276 // Check Phase Shifting and Position
277 uint8_t n;
278 uint32_t p;
279
280 if (maxCorr == corr.uw0mc) {
281 n = 0;
282 p = corr.uw0p;
283 } else if (maxCorr == corr.uw2mc) {
284 n = 4;
285 p = corr.uw2p;
286 } else if (maxCorr == corr.ruw0mc) {
287 n = 1;
288 p = corr.ruw0p;
289 } else if (maxCorr == corr.ruw2mc) {
290 n = 5;
291 p = corr.ruw2p;
292 }
293
294 if (p != 0) {
295 // Shift position
296 char *shiftedPosition = codedData + p;
297 //printf(" Missing bytes for frame: %d\n", p);
298 memcpy(codedData, shiftedPosition, CODEDFRAMESIZE - p); // Copy from p to chunk size to start of codedData
299
300 readsize += chunkSize; // Add what we processed to readsize.
301
302 uint32_t oldChunkSize = chunkSize;
303 chunkSize = (sz - readsize) > p ? p : (sz - readsize); // Read needed bytes to fill a frame.
304 //printf(" Reading for frame missing bytes: %d\n", chunkSize);
305 fread(codedData + CODEDFRAMESIZE - p, chunkSize, 1, input);
306 }
307
308 // Correct Frame Phase
309 //printf(" Fixing packet.\n");
310 fixPacket(codedData, CODEDFRAMESIZE, n);
311
312 // Viterbi
313 //printf(" Decoding using viterbi.\n");
314 init_viterbi27(viterbi, 0);
315 update_viterbi27_blk(viterbi, codedData, FRAMEBITS + 6);
316 chainback_viterbi27(viterbi, decodedData, FRAMEBITS, 0);
317
318 #ifdef CHECK_VITERBI_CORRECTIONS
319 //printf(" Re-encoding.\n");
320 // Calculate Errors
321 convEncode(decodedData, FRAMESIZE, correctedData, CODEDFRAMESIZE);
322 //printf(" Calculating errors.\n");
323 uint32_t errors = calculateError(codedData, correctedData, CODEDFRAMESIZE) / 2;
324 uint32_t signalQuality = 100 - (100 * errors) / FRAMEBITS;
325 #endif
326
327 // De-randomization
328 //printf(" De-randomizing data.\n");
329 uint8_t skipsize = (SYNCWORDSIZE/8);
330 memcpy(decodedData, decodedData + skipsize, FRAMESIZE-skipsize);
331 for (int i=0; i<FRAMESIZE-skipsize; i++) {
332 decodedData[i] ^= pn[i];
333 }
334
335 // Reed-solomon
336 int derrlocs[255];
337 int derrors[4] = { 0, 0, 0, 0 };
338
339 for (int i=0; i<4; i++) {
340 deinterleaveRS(decodedData, rsWorkBuffer, i, 4);
341 derrors[i] = decode_rs_ccsds(rsWorkBuffer, derrlocs, 0, 0);
342 interleaveRS(rsWorkBuffer, rsCorrectedData, i, 4);
343 }
344
345 // If RS returns -1 for all 4 RS Blocks,
346 if (derrors[0] == -1 && derrors[1] == -1 && derrors[2] == -1 && derrors[3] == -1) {
347 printf("Corrupted packet, RS Cannot correct.\n");
348 goto packet_process_end;
349 }
350
351 // Packet Header Filtering
352 uint8_t versionNumber = (*rsCorrectedData) & 0xC0 >> 6;
353 uint8_t scid = ((*rsCorrectedData) & 0x3F) << 2 | (*(rsCorrectedData+1) & 0xC0) >> 6;
354 uint8_t vcid = (*(rsCorrectedData+1)) & 0x3F;
355
356 // Packet Counter from Packet
357 uint32_t counter = *((uint32_t *) (rsCorrectedData+2));
358 counter = swapEndianess(counter);
359 counter &= 0xFFFFFF00;
360 counter = counter >> 8;
361 writeChannel(rsCorrectedData, FRAMESIZE, vcid);
362
363 if (vcid == 63) {
364 //printf("Empty Frame. Discarding.\n");
365 //fwrite(rsCorrectedData, FRAMESIZE - skipsize, 1, fill);
366 } else { //if (vcid == 42) {
367 fwrite(rsCorrectedData, FRAMESIZE - skipsize, 1, output);
368 printf("Frame %lu.\n", frameCount);
369 printf(" Version Number: %u\n", versionNumber);
370 printf(" S/C ID: %u\n", scid);
371 printf(" VC ID: %u\n", vcid);
372 printf(" Packet Number: %u\n", counter);
373 #ifdef CHECK_VITERBI_CORRECTIONS
374 printf(" Viterbi Errors: %u/%u bits\n", errors, FRAMEBITS);
375 printf(" Signal Quality: %u%%\n", signalQuality);
376 #endif
377 printf(" RS Errors: %d %d %d %d\n", derrors[0], derrors[1], derrors[2], derrors[3]);
378 printf(" Sync Correlation: %d\n", maxCorr);
379 switch(n) {
380 case 0: printf(" Max Correlation with 0 degrees Word at %u\n", p); break;
381 case 4: printf(" Max Correlation with 180 degrees Word at %u\n", p); break;
382 case 1: printf(" Max Correlation with 0 degrees Word at %u\n with IQ Reversal", p); break;
383 case 5: printf(" Max Correlation with 180 degrees Word at %u\n with IQ Reversal", p); break;
384 }
385 // Separate M_PDU
386 memcpy(M_PDU, rsCorrectedData + 6, 886);
387
388 uint16_t fhp = (((*M_PDU) & 3) << 8) | *(M_PDU + 1);
389
390 printf(" First Header Pointer: %d\n", fhp);
391
392 memcpy(M_PDU, M_PDU + 2, 884); // Copy CP_PDU to M_PDU start, so its easier to manipulate.
393 //memcpy(M_PDU, M_PDU + fhp, 884 - fhp);
394
395 int packetVersion = ((*M_PDU) & 0xE0) >> 5;
396 int type = (*M_PDU & 0x10) >> 4;
397 int apid = ((*M_PDU & 3) << 8) | *(M_PDU+1);
398
399 int sequenceFlag = *(M_PDU + 2) & 0xC0;
400 int packetSequenceCounter = ((*(M_PDU + 2) & 0x3F) << 8) | *(M_PDU + 3);
401 uint16_t packetLength = *((uint16_t *)(M_PDU + 4));
402
403 printf(" Packet Version: %d - Type: %d - APID: %d\n", packetVersion, type, apid);
404 printf(" Sequence Flag: %d packetSequenceCounter: %d\n", sequenceFlag, packetSequenceCounter);
405 printf(" Packet Length: %d\n", packetLength);
406 }
407packet_process_end:
408 frameCount++;
409 }
410
411 readsize += chunkSize;
412 }
413
414 fclose(input);
415 fclose(output);
416 return 0;
417}
pn.h Raw
1char pn[1020] = {
2 0xff, 0x48, 0x0e, 0xc0, 0x9a, 0x0d, 0x70, 0xbc,
3 0x8e, 0x2c, 0x93, 0xad, 0xa7, 0xb7, 0x46, 0xce,
4 0x5a, 0x97, 0x7d, 0xcc, 0x32, 0xa2, 0xbf, 0x3e,
5 0x0a, 0x10, 0xf1, 0x88, 0x94, 0xcd, 0xea, 0xb1,
6 0xfe, 0x90, 0x1d, 0x81, 0x34, 0x1a, 0xe1, 0x79,
7 0x1c, 0x59, 0x27, 0x5b, 0x4f, 0x6e, 0x8d, 0x9c,
8 0xb5, 0x2e, 0xfb, 0x98, 0x65, 0x45, 0x7e, 0x7c,
9 0x14, 0x21, 0xe3, 0x11, 0x29, 0x9b, 0xd5, 0x63,
10 0xfd, 0x20, 0x3b, 0x02, 0x68, 0x35, 0xc2, 0xf2,
11 0x38, 0xb2, 0x4e, 0xb6, 0x9e, 0xdd, 0x1b, 0x39,
12 0x6a, 0x5d, 0xf7, 0x30, 0xca, 0x8a, 0xfc, 0xf8,
13 0x28, 0x43, 0xc6, 0x22, 0x53, 0x37, 0xaa, 0xc7,
14 0xfa, 0x40, 0x76, 0x04, 0xd0, 0x6b, 0x85, 0xe4,
15 0x71, 0x64, 0x9d, 0x6d, 0x3d, 0xba, 0x36, 0x72,
16 0xd4, 0xbb, 0xee, 0x61, 0x95, 0x15, 0xf9, 0xf0,
17 0x50, 0x87, 0x8c, 0x44, 0xa6, 0x6f, 0x55, 0x8f,
18 0xf4, 0x80, 0xec, 0x09, 0xa0, 0xd7, 0x0b, 0xc8,
19 0xe2, 0xc9, 0x3a, 0xda, 0x7b, 0x74, 0x6c, 0xe5,
20 0xa9, 0x77, 0xdc, 0xc3, 0x2a, 0x2b, 0xf3, 0xe0,
21 0xa1, 0x0f, 0x18, 0x89, 0x4c, 0xde, 0xab, 0x1f,
22 0xe9, 0x01, 0xd8, 0x13, 0x41, 0xae, 0x17, 0x91,
23 0xc5, 0x92, 0x75, 0xb4, 0xf6, 0xe8, 0xd9, 0xcb,
24 0x52, 0xef, 0xb9, 0x86, 0x54, 0x57, 0xe7, 0xc1,
25 0x42, 0x1e, 0x31, 0x12, 0x99, 0xbd, 0x56, 0x3f,
26 0xd2, 0x03, 0xb0, 0x26, 0x83, 0x5c, 0x2f, 0x23,
27 0x8b, 0x24, 0xeb, 0x69, 0xed, 0xd1, 0xb3, 0x96,
28 0xa5, 0xdf, 0x73, 0x0c, 0xa8, 0xaf, 0xcf, 0x82,
29 0x84, 0x3c, 0x62, 0x25, 0x33, 0x7a, 0xac, 0x7f,
30 0xa4, 0x07, 0x60, 0x4d, 0x06, 0xb8, 0x5e, 0x47,
31 0x16, 0x49, 0xd6, 0xd3, 0xdb, 0xa3, 0x67, 0x2d,
32 0x4b, 0xbe, 0xe6, 0x19, 0x51, 0x5f, 0x9f, 0x05,
33 0x08, 0x78, 0xc4, 0x4a, 0x66, 0xf5, 0x58, 0xff,
34 0x48, 0x0e, 0xc0, 0x9a, 0x0d, 0x70, 0xbc, 0x8e,
35 0x2c, 0x93, 0xad, 0xa7, 0xb7, 0x46, 0xce, 0x5a,
36 0x97, 0x7d, 0xcc, 0x32, 0xa2, 0xbf, 0x3e, 0x0a,
37 0x10, 0xf1, 0x88, 0x94, 0xcd, 0xea, 0xb1, 0xfe,
38 0x90, 0x1d, 0x81, 0x34, 0x1a, 0xe1, 0x79, 0x1c,
39 0x59, 0x27, 0x5b, 0x4f, 0x6e, 0x8d, 0x9c, 0xb5,
40 0x2e, 0xfb, 0x98, 0x65, 0x45, 0x7e, 0x7c, 0x14,
41 0x21, 0xe3, 0x11, 0x29, 0x9b, 0xd5, 0x63, 0xfd,
42 0x20, 0x3b, 0x02, 0x68, 0x35, 0xc2, 0xf2, 0x38,
43 0xb2, 0x4e, 0xb6, 0x9e, 0xdd, 0x1b, 0x39, 0x6a,
44 0x5d, 0xf7, 0x30, 0xca, 0x8a, 0xfc, 0xf8, 0x28,
45 0x43, 0xc6, 0x22, 0x53, 0x37, 0xaa, 0xc7, 0xfa,
46 0x40, 0x76, 0x04, 0xd0, 0x6b, 0x85, 0xe4, 0x71,
47 0x64, 0x9d, 0x6d, 0x3d, 0xba, 0x36, 0x72, 0xd4,
48 0xbb, 0xee, 0x61, 0x95, 0x15, 0xf9, 0xf0, 0x50,
49 0x87, 0x8c, 0x44, 0xa6, 0x6f, 0x55, 0x8f, 0xf4,
50 0x80, 0xec, 0x09, 0xa0, 0xd7, 0x0b, 0xc8, 0xe2,
51 0xc9, 0x3a, 0xda, 0x7b, 0x74, 0x6c, 0xe5, 0xa9,
52 0x77, 0xdc, 0xc3, 0x2a, 0x2b, 0xf3, 0xe0, 0xa1,
53 0x0f, 0x18, 0x89, 0x4c, 0xde, 0xab, 0x1f, 0xe9,
54 0x01, 0xd8, 0x13, 0x41, 0xae, 0x17, 0x91, 0xc5,
55 0x92, 0x75, 0xb4, 0xf6, 0xe8, 0xd9, 0xcb, 0x52,
56 0xef, 0xb9, 0x86, 0x54, 0x57, 0xe7, 0xc1, 0x42,
57 0x1e, 0x31, 0x12, 0x99, 0xbd, 0x56, 0x3f, 0xd2,
58 0x03, 0xb0, 0x26, 0x83, 0x5c, 0x2f, 0x23, 0x8b,
59 0x24, 0xeb, 0x69, 0xed, 0xd1, 0xb3, 0x96, 0xa5,
60 0xdf, 0x73, 0x0c, 0xa8, 0xaf, 0xcf, 0x82, 0x84,
61 0x3c, 0x62, 0x25, 0x33, 0x7a, 0xac, 0x7f, 0xa4,
62 0x07, 0x60, 0x4d, 0x06, 0xb8, 0x5e, 0x47, 0x16,
63 0x49, 0xd6, 0xd3, 0xdb, 0xa3, 0x67, 0x2d, 0x4b,
64 0xbe, 0xe6, 0x19, 0x51, 0x5f, 0x9f, 0x05, 0x08,
65 0x78, 0xc4, 0x4a, 0x66, 0xf5, 0x58, 0xff, 0x48,
66 0x0e, 0xc0, 0x9a, 0x0d, 0x70, 0xbc, 0x8e, 0x2c,
67 0x93, 0xad, 0xa7, 0xb7, 0x46, 0xce, 0x5a, 0x97,
68 0x7d, 0xcc, 0x32, 0xa2, 0xbf, 0x3e, 0x0a, 0x10,
69 0xf1, 0x88, 0x94, 0xcd, 0xea, 0xb1, 0xfe, 0x90,
70 0x1d, 0x81, 0x34, 0x1a, 0xe1, 0x79, 0x1c, 0x59,
71 0x27, 0x5b, 0x4f, 0x6e, 0x8d, 0x9c, 0xb5, 0x2e,
72 0xfb, 0x98, 0x65, 0x45, 0x7e, 0x7c, 0x14, 0x21,
73 0xe3, 0x11, 0x29, 0x9b, 0xd5, 0x63, 0xfd, 0x20,
74 0x3b, 0x02, 0x68, 0x35, 0xc2, 0xf2, 0x38, 0xb2,
75 0x4e, 0xb6, 0x9e, 0xdd, 0x1b, 0x39, 0x6a, 0x5d,
76 0xf7, 0x30, 0xca, 0x8a, 0xfc, 0xf8, 0x28, 0x43,
77 0xc6, 0x22, 0x53, 0x37, 0xaa, 0xc7, 0xfa, 0x40,
78 0x76, 0x04, 0xd0, 0x6b, 0x85, 0xe4, 0x71, 0x64,
79 0x9d, 0x6d, 0x3d, 0xba, 0x36, 0x72, 0xd4, 0xbb,
80 0xee, 0x61, 0x95, 0x15, 0xf9, 0xf0, 0x50, 0x87,
81 0x8c, 0x44, 0xa6, 0x6f, 0x55, 0x8f, 0xf4, 0x80,
82 0xec, 0x09, 0xa0, 0xd7, 0x0b, 0xc8, 0xe2, 0xc9,
83 0x3a, 0xda, 0x7b, 0x74, 0x6c, 0xe5, 0xa9, 0x77,
84 0xdc, 0xc3, 0x2a, 0x2b, 0xf3, 0xe0, 0xa1, 0x0f,
85 0x18, 0x89, 0x4c, 0xde, 0xab, 0x1f, 0xe9, 0x01,
86 0xd8, 0x13, 0x41, 0xae, 0x17, 0x91, 0xc5, 0x92,
87 0x75, 0xb4, 0xf6, 0xe8, 0xd9, 0xcb, 0x52, 0xef,
88 0xb9, 0x86, 0x54, 0x57, 0xe7, 0xc1, 0x42, 0x1e,
89 0x31, 0x12, 0x99, 0xbd, 0x56, 0x3f, 0xd2, 0x03,
90 0xb0, 0x26, 0x83, 0x5c, 0x2f, 0x23, 0x8b, 0x24,
91 0xeb, 0x69, 0xed, 0xd1, 0xb3, 0x96, 0xa5, 0xdf,
92 0x73, 0x0c, 0xa8, 0xaf, 0xcf, 0x82, 0x84, 0x3c,
93 0x62, 0x25, 0x33, 0x7a, 0xac, 0x7f, 0xa4, 0x07,
94 0x60, 0x4d, 0x06, 0xb8, 0x5e, 0x47, 0x16, 0x49,
95 0xd6, 0xd3, 0xdb, 0xa3, 0x67, 0x2d, 0x4b, 0xbe,
96 0xe6, 0x19, 0x51, 0x5f, 0x9f, 0x05, 0x08, 0x78,
97 0xc4, 0x4a, 0x66, 0xf5, 0x58, 0xff, 0x48, 0x0e,
98 0xc0, 0x9a, 0x0d, 0x70, 0xbc, 0x8e, 0x2c, 0x93,
99 0xad, 0xa7, 0xb7, 0x46, 0xce, 0x5a, 0x97, 0x7d,
100 0xcc, 0x32, 0xa2, 0xbf, 0x3e, 0x0a, 0x10, 0xf1,
101 0x88, 0x94, 0xcd, 0xea, 0xb1, 0xfe, 0x90, 0x1d,
102 0x81, 0x34, 0x1a, 0xe1, 0x79, 0x1c, 0x59, 0x27,
103 0x5b, 0x4f, 0x6e, 0x8d, 0x9c, 0xb5, 0x2e, 0xfb,
104 0x98, 0x65, 0x45, 0x7e, 0x7c, 0x14, 0x21, 0xe3,
105 0x11, 0x29, 0x9b, 0xd5, 0x63, 0xfd, 0x20, 0x3b,
106 0x02, 0x68, 0x35, 0xc2, 0xf2, 0x38, 0xb2, 0x4e,
107 0xb6, 0x9e, 0xdd, 0x1b, 0x39, 0x6a, 0x5d, 0xf7,
108 0x30, 0xca, 0x8a, 0xfc, 0xf8, 0x28, 0x43, 0xc6,
109 0x22, 0x53, 0x37, 0xaa, 0xc7, 0xfa, 0x40, 0x76,
110 0x04, 0xd0, 0x6b, 0x85, 0xe4, 0x71, 0x64, 0x9d,
111 0x6d, 0x3d, 0xba, 0x36, 0x72, 0xd4, 0xbb, 0xee,
112 0x61, 0x95, 0x15, 0xf9, 0xf0, 0x50, 0x87, 0x8c,
113 0x44, 0xa6, 0x6f, 0x55, 0x8f, 0xf4, 0x80, 0xec,
114 0x09, 0xa0, 0xd7, 0x0b, 0xc8, 0xe2, 0xc9, 0x3a,
115 0xda, 0x7b, 0x74, 0x6c, 0xe5, 0xa9, 0x77, 0xdc,
116 0xc3, 0x2a, 0x2b, 0xf3, 0xe0, 0xa1, 0x0f, 0x18,
117 0x89, 0x4c, 0xde, 0xab, 0x1f, 0xe9, 0x01, 0xd8,
118 0x13, 0x41, 0xae, 0x17, 0x91, 0xc5, 0x92, 0x75,
119 0xb4, 0xf6, 0xe8, 0xd9, 0xcb, 0x52, 0xef, 0xb9,
120 0x86, 0x54, 0x57, 0xe7, 0xc1, 0x42, 0x1e, 0x31,
121 0x12, 0x99, 0xbd, 0x56, 0x3f, 0xd2, 0x03, 0xb0,
122 0x26, 0x83, 0x5c, 0x2f, 0x23, 0x8b, 0x24, 0xeb,
123 0x69, 0xed, 0xd1, 0xb3, 0x96, 0xa5, 0xdf, 0x73,
124 0x0c, 0xa8, 0xaf, 0xcf, 0x82, 0x84, 0x3c, 0x62,
125 0x25, 0x33, 0x7a, 0xac, 0x7f, 0xa4, 0x07, 0x60,
126 0x4d, 0x06, 0xb8, 0x5e, 0x47, 0x16, 0x49, 0xd6,
127 0xd3, 0xdb, 0xa3, 0x67, 0x2d, 0x4b, 0xbe, 0xe6,
128 0x19, 0x51, 0x5f, 0x9f, 0x05, 0x08, 0x78, 0xc4,
129 0x4a, 0x66, 0xf5, 0x58
130};