Последняя активность 1 month ago

LRIT Packet Decoder

Версия 57a2c46ec479f6a3a50a5cdac05f91a7074ce051

decoder.c Исходник
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 RSBLOCKS 4
29#define RSPARITYSIZE 32
30#define RSPARITYBLOCK (RSPARITYSIZE * RSBLOCKS)
31
32#define VITPOLYA 0x4F
33#define VITPOLYB 0x6D
34
35#define CHECK_VITERBI_CORRECTIONS
36
37#define CODEDFRAMESIZE (FRAMEBITS * 2)
38#define SYNCWORDSIZEDOUBLE (SYNCWORDSIZE * 2)
39#define PARITY_OFFSET 892
40
41const uint64_t UW0 = 0xfca2b63db00d9794;
42const uint64_t UW2 = 0x035d49c24ff2686b;
43const uint64_t REVUW0 = 0xfc51793e700e6b68;
44const uint64_t REVUW2 = 0x03ae86c18ff19497;
45
46typedef struct {
47 uint32_t uw0mc;
48 uint32_t uw0p;
49 uint32_t uw2mc;
50 uint32_t uw2p;
51 uint32_t ruw0mc;
52 uint32_t ruw0p;
53 uint32_t ruw2mc;
54 uint32_t ruw2p;
55} correlation_t ;
56
57uint8_t UW0b[SYNCWORDSIZE * 2];
58uint8_t UW2b[SYNCWORDSIZE * 2];
59uint8_t REVUW0b[SYNCWORDSIZE * 2];
60uint8_t REVUW2b[SYNCWORDSIZE * 2];
61
62uint8_t codedData[CODEDFRAMESIZE];
63uint8_t decodedData[FRAMESIZE];
64uint8_t correctedData[CODEDFRAMESIZE];
65uint8_t rsCorrectedData[FRAMESIZE];
66uint8_t rsWorkBuffer[255];
67
68uint8_t M_PDU[886];
69
70int viterbiPolynomial[2] = {VITPOLYA, VITPOLYB};
71
72
73void initUW();
74void checkCorrelation(uint8_t *buffer, int buffLength, correlation_t *corr);
75void resetCorrelation(correlation_t * corr);
76uint32_t hardCorrelate(uint8_t dataByte, uint8_t wordByte);
77void fixPacket(uint8_t *buffer, int buffLength, uint8_t n);
78void convEncode(uint8_t *data, int dataLength, uint8_t *output, int outputLen);
79uint32_t calculateError(uint8_t *original, uint8_t *corrected, int length);
80void deinterleaveRS(uint8_t *data, uint8_t *rsbuff, uint8_t pos, uint8_t I);
81void interleaveRS(uint8_t *idata, uint8_t *outbuff, uint8_t pos, uint8_t I);
82void writeChannel(uint8_t *data, int size, uint16_t vcid);
83// Code
84
85uint32_t swapEndianess(uint32_t num) {
86 return ((num>>24)&0xff) | ((num<<8)&0xff0000) | ((num>>8)&0xff00) | ((num<<24)&0xff000000);
87}
88
89uint32_t maxCorrelation(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
90 uint32_t f = (a > b ? a : b);
91 uint32_t g = (c > d ? c : d);
92 return f > g ? f : g;
93}
94
95
96void initUW() {
97 printf("Converting Sync Words to Soft Data\n");
98 for (int i = 0; i < SYNCWORDSIZEDOUBLE; i++) {
99 UW0b[i] = (UW0 >> (SYNCWORDSIZEDOUBLE-i-1)) & 1 ? 0xFF : 0x00;
100 UW2b[i] = (UW2 >> (SYNCWORDSIZEDOUBLE-i-1)) & 1 ? 0xFF : 0x00;
101 REVUW0b[i] = (REVUW0 >> (SYNCWORDSIZEDOUBLE-i-1)) & 1 ? 0xFF : 0x00;
102 REVUW2b[i] = (REVUW2 >> (SYNCWORDSIZEDOUBLE-i-1)) & 1 ? 0xFF : 0x00;
103 }
104}
105
106uint32_t hardCorrelate(uint8_t dataByte, uint8_t wordByte) {
107 //1 if (a > 127 and b == 255) or (a < 127 and b == 0) else 0
108 return (dataByte >= 127 & wordByte == 0) | (dataByte < 127 & wordByte == 255);
109}
110
111void checkCorrelation(uint8_t *buffer, int buffLength, correlation_t *corr) {
112 resetCorrelation(corr);
113 for (int i = 0; i < buffLength - SYNCWORDSIZEDOUBLE; i++) {
114 uint32_t uw0c = 0;
115 uint32_t uw2c = 0;
116 uint32_t ruw0c = 0;
117 uint32_t ruw2c = 0;
118
119 for (int k = 0; k < SYNCWORDSIZEDOUBLE; k++) {
120 uw0c += hardCorrelate(buffer[i+k], UW0b[k]);
121 uw2c += hardCorrelate(buffer[i+k], UW2b[k]);
122 ruw0c += hardCorrelate(buffer[i+k], REVUW0b[k]);
123 ruw2c += hardCorrelate(buffer[i+k], REVUW2b[k]);
124 }
125
126 corr->uw0p = uw0c > corr->uw0mc ? i : corr->uw0p;
127 corr->uw2p = uw2c > corr->uw2mc ? i : corr->uw2p;
128 corr->ruw0p = ruw0c > corr->ruw0mc ? i : corr->ruw0p;
129 corr->ruw2p = ruw2c > corr->ruw2mc ? i : corr->ruw2p;
130
131 corr->uw0mc = uw0c > corr->uw0mc ? uw0c : corr->uw0mc;
132 corr->uw2mc = uw2c > corr->uw2mc ? uw2c : corr->uw2mc;
133 corr->ruw0mc = ruw0c > corr->ruw0mc ? ruw0c : corr->ruw0mc;
134 corr->ruw2mc = ruw2c > corr->ruw2mc ? ruw2c : corr->ruw2mc;
135 }
136}
137
138void resetCorrelation(correlation_t * corr) {
139 memset(corr, 0x00, sizeof(correlation_t));
140}
141
142void fixPacket(uint8_t *buffer, int buffLength, uint8_t n) {
143 if (n != 0) {
144 for (int i=0; i < buffLength; i+=2) {
145 if (n % 2) { // Process IQ Inversion
146 char a = buffer[i];
147 buffer[i] = buffer[i+1];
148 buffer[i+1] = a;
149 }
150
151 if (n >= 4) { // Process 180 phase shift, aka inverted bits
152 buffer[i] ^= 0xFF;
153 buffer[i+1] ^= 0xFF;
154 }
155 }
156 }
157}
158
159uint32_t calculateError(uint8_t *original, uint8_t *corrected, int length) {
160 uint32_t errors = 0;
161 for (int i=0; i<length; i++) {
162 errors += hardCorrelate(original[i], ~corrected[i]);
163 }
164
165 return errors;
166}
167
168void convEncode(uint8_t *data, int dataLength, uint8_t *output, int outputLen) {
169 unsigned int encstate = 0;
170 uint8_t c;
171 uint32_t pos = 0;
172 uint32_t opos = 0;
173
174 memset(output, 0x00, outputLen);
175 while (pos < dataLength && (pos * 16) < outputLen) {
176 c = data[pos];
177 for(int i=7;i>=0;i--){
178 encstate = (encstate << 1) | ((c >> 7) & 1);
179 c <<= 1;
180 output[opos] = ~(0 - parity(encstate & viterbiPolynomial[0]));
181 output[opos+1] = ~(0 - parity(encstate & viterbiPolynomial[1]));
182
183 opos += 2;
184 }
185 pos++;
186 }
187}
188
189void printBuff(uint8_t *buff, int length) {
190 int countlen = (length > 40 ? 40 : length);
191 for (int i=0; i<countlen; i++) {
192 if (i % 8 == 0 && i != 0) {
193 printf("\n");
194 }
195 printf("%d ", buff[i]);
196 }
197 printf("\n");
198}
199
200void deinterleaveRS(uint8_t *data, uint8_t *rsbuff, uint8_t pos, uint8_t I) {
201 // Copy data
202 for (int i=0; i<223; i++) {
203 rsbuff[i] = data[i*I + pos];
204 }
205 // Copy parity
206 for (int i=0; i<32; i++) {
207 rsbuff[i+223] = data[PARITY_OFFSET + i*I + pos];
208 }
209}
210
211void interleaveRS(uint8_t *idata, uint8_t *outbuff, uint8_t pos, uint8_t I) {
212 // Copy data
213 for (int i=0; i<223; i++) {
214 outbuff[i*I + pos] = idata[i];
215 }
216 // Copy parity - Not needed here, but I do.
217 for (int i=0; i<32; i++) {
218 outbuff[PARITY_OFFSET + i*I + pos] = idata[i+223];
219 }
220}
221
222void writeChannel(uint8_t *data, int size, uint16_t vcid) {
223 char filename[256];
224 sprintf(filename, "channels/channel_%d.bin", vcid);
225 FILE *f = fopen(filename, "a+");
226 fwrite(data, size, 1, f);
227 fclose(f);
228}
229
230int main(int argc,char *argv[]) {
231
232 if (argc < 3) {
233 printf("Usage: ./decoder inputfile outputfile");
234 return 1;
235 }
236
237 char *inputfile = argv[1];
238 char *outputfile = argv[2];
239 void *viterbi;
240 uint32_t averageVitCorrections = 0;
241 uint32_t averageRSCorrections = 0;
242 correlation_t corr;
243
244 printf("Opening files\n");
245 FILE *input = fopen(inputfile, "r");
246 FILE *output = fopen(outputfile, "w");
247
248 initUW();
249
250 printf("Initializing Viterbi\n");
251 set_viterbi27_polynomial(viterbiPolynomial);
252 if((viterbi = create_viterbi27(FRAMEBITS)) == NULL){
253 printf("create_viterbi27 failed\n");
254 exit(1);
255 }
256
257 fseek(input, 0L, SEEK_END);
258 uint64_t sz = ftell(input);
259 fseek(input, 0L, SEEK_SET);
260 printf("Input size is %lu\n", sz);
261
262 uint64_t readsize = 0;
263 uint64_t frameCount = 1;
264
265 while (readsize < sz) {
266 // Read Data
267 uint32_t chunkSize = sz - readsize > CODEDFRAMESIZE ? CODEDFRAMESIZE : sz - readsize;
268 memset(codedData, 0x00, CODEDFRAMESIZE);
269 fread(codedData, chunkSize, 1, input);
270
271 //printBuff(codedData, chunkSize);
272 // Check Correlation
273 checkCorrelation(codedData, chunkSize, &corr);
274 // Get Max Correlation
275 uint32_t maxCorr = maxCorrelation(corr.uw0mc, corr.uw2mc, corr.ruw0mc, corr.ruw2mc);
276
277 if (maxCorr < MINCORRELATIONBITS) {
278 printf(" Skipping read. Correlation %d less than required %d.\n", maxCorr, MINCORRELATIONBITS);
279 } else {
280 // Check Phase Shifting and Position
281 uint8_t n;
282 uint32_t p;
283
284 if (maxCorr == corr.uw0mc) {
285 n = 0;
286 p = corr.uw0p;
287 } else if (maxCorr == corr.uw2mc) {
288 n = 4;
289 p = corr.uw2p;
290 } else if (maxCorr == corr.ruw0mc) {
291 n = 1;
292 p = corr.ruw0p;
293 } else if (maxCorr == corr.ruw2mc) {
294 n = 5;
295 p = corr.ruw2p;
296 }
297
298 if (p != 0) {
299 // Shift position
300 char *shiftedPosition = codedData + p;
301 //printf(" Missing bytes for frame: %d\n", p);
302 memcpy(codedData, shiftedPosition, CODEDFRAMESIZE - p); // Copy from p to chunk size to start of codedData
303
304 readsize += chunkSize; // Add what we processed to readsize.
305
306 uint32_t oldChunkSize = chunkSize;
307 chunkSize = (sz - readsize) > p ? p : (sz - readsize); // Read needed bytes to fill a frame.
308 //printf(" Reading for frame missing bytes: %d\n", chunkSize);
309 fread(codedData + CODEDFRAMESIZE - p, chunkSize, 1, input);
310 }
311
312 // Correct Frame Phase
313 //printf(" Fixing packet.\n");
314 fixPacket(codedData, CODEDFRAMESIZE, n);
315
316 // Viterbi
317 //printf(" Decoding using viterbi.\n");
318 init_viterbi27(viterbi, 0);
319 update_viterbi27_blk(viterbi, codedData, FRAMEBITS + 6);
320 chainback_viterbi27(viterbi, decodedData, FRAMEBITS, 0);
321
322 #ifdef CHECK_VITERBI_CORRECTIONS
323 //printf(" Re-encoding.\n");
324 // Calculate Errors
325 convEncode(decodedData, FRAMESIZE, correctedData, CODEDFRAMESIZE);
326 //printf(" Calculating errors.\n");
327 uint32_t errors = calculateError(codedData, correctedData, CODEDFRAMESIZE) / 2;
328 float signalErrors = (100.f * errors) / FRAMEBITS; // 0 to 16
329 signalErrors = 100 - (signalErrors * 10);
330 uint32_t signalQuality = signalErrors < 0 ? 0 : signalErrors;
331 #endif
332
333 // De-randomization
334 //printf(" De-randomizing data.\n");
335 uint8_t skipsize = (SYNCWORDSIZE/8);
336 memcpy(decodedData, decodedData + skipsize, FRAMESIZE-skipsize);
337 for (int i=0; i<FRAMESIZE-skipsize; i++) {
338 decodedData[i] ^= pn[i];
339 }
340
341 // Reed-solomon
342 int derrlocs[255];
343 int derrors[4] = { 0, 0, 0, 0 };
344
345 for (int i=0; i<RSBLOCKS; i++) {
346 deinterleaveRS(decodedData, rsWorkBuffer, i, RSBLOCKS);
347 derrors[i] = decode_rs_ccsds(rsWorkBuffer, derrlocs, 0, 0);
348 interleaveRS(rsWorkBuffer, rsCorrectedData, i, RSBLOCKS);
349 }
350
351 // If RS returns -1 for all 4 RS Blocks,
352 if (derrors[0] == -1 && derrors[1] == -1 && derrors[2] == -1 && derrors[3] == -1) {
353 #ifdef CHECK_VITERBI_CORRECTIONS
354 printf(" Viterbi Errors: %u/%u bits\n", errors, FRAMEBITS);
355 printf(" Signal Quality: %u%%\n", signalQuality);
356 printf(" Sync Correlation: %d\n", maxCorr);
357 #endif
358 printf(" Corrupted packet, RS Cannot correct. Dropping.\n");
359 goto packet_process_end;
360 } else {
361 averageRSCorrections += derrors[0] != -1 ? derrors[0] : 0;
362 averageRSCorrections += derrors[1] != -1 ? derrors[1] : 0;
363 averageRSCorrections += derrors[2] != -1 ? derrors[2] : 0;
364 averageRSCorrections += derrors[3] != -1 ? derrors[3] : 0;
365 }
366
367 // Packet Header Filtering
368 uint8_t versionNumber = (*rsCorrectedData) & 0xC0 >> 6;
369 uint8_t scid = ((*rsCorrectedData) & 0x3F) << 2 | (*(rsCorrectedData+1) & 0xC0) >> 6;
370 uint8_t vcid = (*(rsCorrectedData+1)) & 0x3F;
371
372 // Packet Counter from Packet
373 uint32_t counter = *((uint32_t *) (rsCorrectedData+2));
374 counter = swapEndianess(counter);
375 counter &= 0xFFFFFF00;
376 counter = counter >> 8;
377 writeChannel(rsCorrectedData, FRAMESIZE - RSPARITYBLOCK - (SYNCWORDSIZE/8), vcid);
378
379 if (vcid == 63) {
380 //printf("Empty Frame. Discarding.\n");
381 //fwrite(rsCorrectedData, FRAMESIZE - skipsize, 1, fill);
382 } else { //if (vcid == 42) {
383 fwrite(rsCorrectedData, FRAMESIZE - skipsize, 1, output);
384 printf("Frame %lu.\n", frameCount);
385 printf(" Version Number: %u\n", versionNumber);
386 printf(" S/C ID: %u\n", scid);
387 printf(" VC ID: %u\n", vcid);
388 printf(" Packet Number: %u\n", counter);
389 #ifdef CHECK_VITERBI_CORRECTIONS
390 printf(" Viterbi Errors: %u/%u bits\n", errors, FRAMEBITS);
391 printf(" Signal Quality: %u%%\n", signalQuality);
392 #endif
393 printf(" RS Errors: %d %d %d %d\n", derrors[0], derrors[1], derrors[2], derrors[3]);
394 printf(" Sync Correlation: %d\n", maxCorr);
395 switch(n) {
396 case 0: printf(" Max Correlation with 0 degrees Word at %u\n", p); break;
397 case 4: printf(" Max Correlation with 180 degrees Word at %u\n", p); break;
398 case 1: printf(" Max Correlation with 0 degrees Word at %u\n with IQ Reversal", p); break;
399 case 5: printf(" Max Correlation with 180 degrees Word at %u\n with IQ Reversal", p); break;
400 }
401 }
402packet_process_end:
403 averageVitCorrections += errors;
404 frameCount++;
405 }
406
407 readsize += chunkSize;
408 }
409
410 averageVitCorrections /= frameCount;
411 averageRSCorrections /= frameCount * 4;
412
413 printf("Average Viterbi Correction: %u\n", averageVitCorrections);
414 printf("Average ReedSolomon Correction: %u\n", averageRSCorrections);
415
416 fclose(input);
417 fclose(output);
418 return 0;
419}
pn.h Исходник
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};