Last active
June 5, 2022 13:32
-
-
Save NT7S/6e38d8a35d153f015d476bc49b40effb to your computer and use it in GitHub Desktop.
FT8 Encoding test script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* \file | |
* Functions and types for CRC checks. | |
* | |
* Generated on Thu Dec 6 17:52:34 2018 | |
* by pycrc v0.9.1, https://pycrc.org | |
* using the configuration: | |
* - Width = 14 | |
* - Poly = 0x2757 | |
* - XorIn = Undefined | |
* - ReflectIn = Undefined | |
* - XorOut = Undefined | |
* - ReflectOut = Undefined | |
* - Algorithm = bit-by-bit | |
*/ | |
#include "crc14.h" /* include the header file generated with pycrc */ | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <stdbool.h> | |
static crc_t crc_reflect(crc_t data, size_t data_len); | |
crc_t crc_reflect(crc_t data, size_t data_len) | |
{ | |
unsigned int i; | |
crc_t ret; | |
ret = data & 0x01; | |
for (i = 1; i < data_len; i++) { | |
data >>= 1; | |
ret = (ret << 1) | (data & 0x01); | |
} | |
return ret; | |
} | |
crc_t crc_init(const crc_cfg_t *cfg) | |
{ | |
unsigned int i; | |
bool bit; | |
crc_t crc = cfg->xor_in; | |
for (i = 0; i < 14; i++) { | |
bit = crc & 0x01; | |
if (bit) { | |
crc = ((crc ^ 0x2757) >> 1) | 0x2000; | |
} else { | |
crc >>= 1; | |
} | |
} | |
return crc & 0x3fff; | |
} | |
crc_t crc_update(const crc_cfg_t *cfg, crc_t crc, const void *data, size_t data_len) | |
{ | |
const unsigned char *d = (const unsigned char *)data; | |
unsigned int i; | |
bool bit; | |
unsigned char c; | |
while (data_len--) { | |
if (cfg->reflect_in) { | |
c = crc_reflect(*d++, 8); | |
} else { | |
c = *d++; | |
} | |
for (i = 0; i < 8; i++) { | |
bit = crc & 0x2000; | |
crc = (crc << 1) | ((c >> (7 - i)) & 0x01); | |
if (bit) { | |
crc ^= 0x2757; | |
} | |
} | |
crc &= 0x3fff; | |
} | |
return crc & 0x3fff; | |
} | |
crc_t crc_finalize(const crc_cfg_t *cfg, crc_t crc) | |
{ | |
unsigned int i; | |
bool bit; | |
for (i = 0; i < 14; i++) { | |
bit = crc & 0x2000; | |
crc <<= 1; | |
if (bit) { | |
crc ^= 0x2757; | |
} | |
} | |
if (cfg->reflect_out) { | |
crc = crc_reflect(crc, 14); | |
} | |
return (crc ^ cfg->xor_out) & 0x3fff; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* \file | |
* Functions and types for CRC checks. | |
* | |
* Generated on Thu Dec 6 17:52:01 2018 | |
* by pycrc v0.9.1, https://pycrc.org | |
* using the configuration: | |
* - Width = 14 | |
* - Poly = 0x2757 | |
* - XorIn = Undefined | |
* - ReflectIn = Undefined | |
* - XorOut = Undefined | |
* - ReflectOut = Undefined | |
* - Algorithm = bit-by-bit | |
* | |
* This file defines the functions crc_init(), crc_update() and crc_finalize(). | |
* | |
* The crc_init() function returns the inital \c crc value and must be called | |
* before the first call to crc_update(). | |
* Similarly, the crc_finalize() function must be called after the last call | |
* to crc_update(), before the \c crc is being used. | |
* is being used. | |
* | |
* The crc_update() function can be called any number of times (including zero | |
* times) in between the crc_init() and crc_finalize() calls. | |
* | |
* This pseudo-code shows an example usage of the API: | |
* \code{.c} | |
* crc_cfg_t cfg = { | |
* 0, // reflect_in | |
* 0, // xor_in | |
* 0, // reflect_out | |
* 0, // xor_out | |
* }; | |
* crc_t crc; | |
* unsigned char data[MAX_DATA_LEN]; | |
* size_t data_len; | |
* | |
* crc = crc_init(&cfg); | |
* while ((data_len = read_data(data, MAX_DATA_LEN)) > 0) { | |
* crc = crc_update(&cfg, crc, data, data_len); | |
* } | |
* crc = crc_finalize(&cfg, crc); | |
* \endcode | |
*/ | |
#ifndef CRC14_H | |
#define CRC14_H | |
#include <stdlib.h> | |
#include <stdint.h> | |
#include <stdbool.h> | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
/** | |
* The definition of the used algorithm. | |
* | |
* This is not used anywhere in the generated code, but it may be used by the | |
* application code to call algorithm-specific code, if desired. | |
*/ | |
#define CRC_ALGO_BIT_BY_BIT 1 | |
/** | |
* The type of the CRC values. | |
* | |
* This type must be big enough to contain at least 14 bits. | |
*/ | |
typedef uint_fast16_t crc_t; | |
/** | |
* The configuration type of the CRC algorithm. | |
*/ | |
typedef struct { | |
bool reflect_in; /*!< Whether the input shall be reflected or not */ | |
crc_t xor_in; /*!< The initial value of the register */ | |
bool reflect_out; /*!< Whether the output shall be reflected or not */ | |
crc_t xor_out; /*!< The value which shall be XOR-ed to the final CRC value */ | |
} crc_cfg_t; | |
/** | |
* Calculate the initial crc value. | |
* | |
* \param[in] cfg A pointer to an initialised crc_cfg_t structure. | |
* \return The initial crc value. | |
*/ | |
crc_t crc_init(const crc_cfg_t *cfg); | |
/** | |
* Update the crc value with new data. | |
* | |
* \param[in] crc The current crc value. | |
* \param[in] cfg A pointer to an initialised crc_cfg_t structure. | |
* \param[in] data Pointer to a buffer of \a data_len bytes. | |
* \param[in] data_len Number of bytes in the \a data buffer. | |
* \return The updated crc value. | |
*/ | |
crc_t crc_update(const crc_cfg_t *cfg, crc_t crc, const void *data, size_t data_len); | |
/** | |
* Calculate the final crc value. | |
* | |
* \param[in] cfg A pointer to an initialised crc_cfg_t structure. | |
* \param[in] crc The current crc value. | |
* \return The final crc value. | |
*/ | |
crc_t crc_finalize(const crc_cfg_t *cfg, crc_t crc); | |
#ifdef __cplusplus | |
} /* closing brace for extern "C" */ | |
#endif | |
#endif /* CRC14_H */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <string.h> | |
#include <ctype.h> | |
#include "crc14.h" | |
#include "generator.h" | |
#define FT8_BIT_COUNT 174 | |
#define FT8_ENCODE_COUNT 79 | |
int8_t hex2int(char ch) | |
{ | |
if (ch >= '0' && ch <= '9') | |
return ch - '0'; | |
if (ch >= 'A' && ch <= 'F') | |
return ch - 'A' + 10; | |
if (ch >= 'a' && ch <= 'f') | |
return ch - 'a' + 10; | |
return -1; | |
} | |
uint8_t ft_code(char c) | |
{ | |
/* Validate the input then return the proper integer code */ | |
// Return 255 as an error code if the char is not allowed | |
if(isdigit(c)) | |
{ | |
return (uint8_t)(c) - 47; | |
} | |
else if(c >= 'A' && c <= 'Z') | |
{ | |
return (uint8_t)(c) - 54; | |
} | |
else if(c == ' ') | |
{ | |
return 0; | |
} | |
else if(c == '+') | |
{ | |
return 38; | |
} | |
else if(c == '-') | |
{ | |
return 39; | |
} | |
else if(c == '.') | |
{ | |
return 40; | |
} | |
else if(c == '/') | |
{ | |
return 41; | |
} | |
else if(c == '?') | |
{ | |
return 42; | |
} | |
else | |
{ | |
return 255; | |
} | |
} | |
void ft_message_prep(char * message) | |
{ | |
uint8_t i; | |
char temp_msg[14]; | |
snprintf(temp_msg, 14, "%*s", 13, message); | |
// Convert all chars to uppercase | |
for(i = 0; i < 13; i++) | |
{ | |
if(islower(temp_msg[i])) | |
{ | |
temp_msg[i] = toupper(temp_msg[i]); | |
} | |
} | |
strcpy(message, temp_msg); | |
} | |
void ft8_bit_packing(char* message, uint8_t* codeword) | |
{ | |
// Just encoding type 0 free text and type 0.5 telemetry for now | |
// The bit packing algorithm is: | |
// sum(message(pos) * 42^pos) | |
uint8_t i3 = 0; | |
uint8_t n3 = 0; | |
uint8_t qa[10]; | |
uint8_t qb[10]; | |
char c18[19]; | |
bool telem = false; | |
char temp_msg[19]; | |
memset(qa, 0, 10); | |
memset(qb, 0, 10); | |
uint8_t i, j, x, i0; | |
uint32_t ireg = 0; | |
// See if this is a telemetry message | |
// Has to be hex digits, can be no more than 18 | |
for(i = 0; i < 19; ++i) | |
{ | |
if(message[i] == 0 || message[i] == ' ') | |
{ | |
break; | |
} | |
else if(hex2int(message[i]) == -1) | |
{ | |
telem = false; | |
break; | |
} | |
else | |
{ | |
c18[i] = message[i]; | |
telem = true; | |
} | |
} | |
// If telemetry | |
if(telem) | |
{ | |
// Get the first 18 hex digits | |
for(i = 0; i < strlen(message); ++i) | |
{ | |
i0 = i; | |
if(message[i] == ' ') | |
{ | |
--i0; | |
break; | |
} | |
} | |
memset(c18, 0, 19); | |
memmove(c18, message, i0 + 1); | |
snprintf(temp_msg, 19, "%*s", 18, c18); | |
// Convert all chars to uppercase | |
for(i = 0; i < strlen(temp_msg); i++) | |
{ | |
if(islower(temp_msg[i])) | |
{ | |
temp_msg[i] = toupper(temp_msg[i]); | |
} | |
} | |
strcpy(message, temp_msg); | |
printf("Telemetry Message:\n%s\n\n", message); | |
uint8_t temp_int; | |
temp_int = message[0] == ' ' ? 0 : hex2int(message[0]); | |
for(i = 1; i < 4; ++i) | |
{ | |
codeword[i - 1] = (((temp_int << i) & 0x8) >> 3) & 1; | |
// printf("%u\n", i - 1); | |
} | |
temp_int = message[1] == ' ' ? 0 : hex2int(message[1]); | |
for(i = 0; i < 4; ++i) | |
{ | |
codeword[i + 3] = (((temp_int << i) & 0x8) >> 3) & 1; | |
// printf("%u\n", i + 3); | |
} | |
for(i = 0; i < 8; ++i) | |
{ | |
if(message[2 * i + 2] == ' ') | |
{ | |
temp_int = 0; | |
} | |
else | |
{ | |
temp_int = hex2int(message[2 * i + 2]); | |
} | |
// printf("%u %u\n", 2 * i + 2, temp_int); | |
// temp_int = message[2 * i + 2] == ' ' ? 0 : hex2int(message[2 * i + 2]); | |
for(j = 0; j < 4; ++j) | |
{ | |
codeword[(i + 1) * 8 + j - 1] = (((temp_int << j) & 0x8) >> 3) & 1; | |
// printf("%u\n", codeword[(i + 1) * 8 + j - 1]); | |
} | |
if(message[2 * i + 3] == ' ') | |
{ | |
temp_int = 0; | |
} | |
else | |
{ | |
temp_int = hex2int(message[2 * i + 3]); | |
} | |
// printf("%u %u\n", 2 * i + 3, temp_int); | |
// temp_int = message[2 * i + 3] == ' ' ? 0 : hex2int(message[2 * i + 3]); | |
for(j = 0; j < 4; ++j) | |
{ | |
codeword[(i + 1) * 8 + j + 3] = (((temp_int << j) & 0x8) >> 3) & 1; | |
// printf("%u\n", codeword[(i + 1) * 8 + j + 3]); | |
} | |
} | |
i3 = 0; | |
n3 = 5; | |
} | |
else | |
{ | |
ft_message_prep(message); | |
printf("Message:\n%s\n\n", message); | |
for(i = 0; i < 13; ++i) | |
{ | |
x = ft_code(message[i]); | |
// mult | |
ireg = 0; | |
for(j = 0; j < 9; ++j) | |
{ | |
ireg = (uint8_t)qa[j] * 42 + (uint8_t)((ireg >> 8) & 0xff); | |
qb[j] = (uint8_t)(ireg & 0xff); | |
} | |
qb[9] = (uint8_t)((ireg >> 8) & 0xff); | |
// add | |
ireg = x << 8; | |
for(j = 0; j < 9; ++j) | |
{ | |
ireg = (uint8_t)qb[j] + (uint8_t)((ireg >> 8) & 0xff); | |
qa[j] = (uint8_t)(ireg & 0xff); | |
} | |
qa[9] = (uint8_t)((ireg >> 8) & 0xff); | |
} | |
// Format bits to output array | |
for(i = 1; i < 8; ++i) | |
{ | |
codeword[i - 1] = (((qa[8] << i) & 0x80) >> 7) & 1; | |
} | |
for(i = 0; i < 8; ++i) | |
{ | |
for(j = 0; j < 8; ++j) | |
{ | |
codeword[(i + 1) * 8 + j - 1] = (((qa[7 - i] << j) & 0x80) >> 7) & 1; | |
} | |
} | |
} | |
// Write the message type bits at the end of the array | |
for(i = 0; i < 3; ++i) | |
{ | |
codeword[i + 71] = (n3 >> i) & 1; | |
} | |
for(i = 0; i < 3; ++i) | |
{ | |
codeword[i + 74] = (i3 >> i) & 1; | |
} | |
} | |
void ft8_encode(uint8_t* codeword, uint8_t* symbols) | |
{ | |
const uint8_t FT8_N = 174; | |
const uint8_t FT8_K = 91; | |
const uint8_t FT8_M = FT8_N - FT8_K; | |
uint8_t tempchar[FT8_K]; | |
uint8_t message91[FT8_K]; | |
uint8_t pchecks[FT8_M]; | |
uint8_t i1_msg_bytes[12]; | |
uint8_t i, j; | |
uint16_t ncrc14; | |
crc_t crc; | |
crc_cfg_t crc_cfg; | |
crc_cfg.reflect_in = 0; | |
crc_cfg.xor_in = 0; | |
crc_cfg.reflect_out = 0; | |
crc_cfg.xor_out = 0; | |
crc = crc_init(&crc_cfg); | |
// Add 14-bit CRC to form 91-bit message | |
memset(tempchar, 0, 91); | |
memcpy(tempchar, codeword, 77); | |
tempchar[77] = 0; | |
tempchar[78] = 0; | |
tempchar[79] = 0; | |
memset(i1_msg_bytes, 0, 12); | |
for(i = 0; i < 10; ++i) | |
{ | |
for(j = 0; j < 8; ++j) | |
{ | |
i1_msg_bytes[i] <<= 1; | |
i1_msg_bytes[i] |= tempchar[i * 8 + j]; | |
} | |
} | |
ncrc14 = crc_update(&crc_cfg, crc, (unsigned char *)i1_msg_bytes, 12); | |
crc = crc_finalize(&crc_cfg, crc); | |
for(i = 0; i < 14; ++i) | |
{ | |
if((((ncrc14 << (i + 2)) & 0x8000) >> 15) & 1) | |
{ | |
tempchar[i + 77] = 1; | |
} | |
else | |
{ | |
tempchar[i + 77] = 0; | |
} | |
} | |
memcpy(message91, tempchar, 91); | |
for(i = 0; i < FT8_M; ++i) | |
{ | |
uint32_t nsum = 0; | |
for(j = 0; j < FT8_K; ++j) | |
{ | |
uint8_t bits = generator_bits[i][j / 8]; | |
bits <<= (j % 8); | |
bits &= 0x80; | |
bits >>= 7; | |
bits &= 1; | |
nsum += (message91[j] * bits); | |
} | |
pchecks[i] = nsum % 2; | |
} | |
memcpy(symbols, message91, FT8_K); | |
memcpy(symbols + FT8_K, pchecks, FT8_M); | |
} | |
void ft8_merge_sync_vector(uint8_t* symbols, uint8_t* output) | |
{ | |
const uint8_t costas7x7[7] = {3, 1, 4, 0, 6, 5, 2}; | |
const uint8_t graymap[8] = {0, 1, 3, 2, 5, 6, 4, 7}; | |
uint8_t i, j, k, idx; | |
// Insert Costas sync arrays | |
memcpy(output, costas7x7, 7); | |
memcpy(output + 36, costas7x7, 7); | |
memcpy(output + FT8_ENCODE_COUNT - 7, costas7x7, 7); | |
k = 6; | |
for(j = 0; j < 58; ++j) // 58 data symbols | |
{ | |
i = 3 * j; | |
++k; | |
if(j == 29) | |
{ | |
k += 7; | |
} | |
idx = symbols[i] * 4 + symbols[i + 1] * 2 + symbols[i + 2]; | |
output[k] = graymap[idx]; | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
uint8_t i; | |
char message[20]; | |
strcpy(message, argv[1]); | |
// char message[14] = "NT7S CN85"; | |
// char message[14] = "ABCDEFGHIJKLM"; | |
// Ensure that the message text conforms to standards | |
// -------------------------------------------------- | |
// ft_message_prep(message); | |
// Print the message | |
// printf("Message:\n%s\n\n", message); | |
// Bit packing | |
// ----------- | |
uint8_t c[77]; | |
memset(c, 0, 77); | |
ft8_bit_packing(message, c); | |
// Print the 77 1-bit symbols for debugging | |
printf("Packed message, 1-bit symbols:\n"); | |
for(i = 0; i < 77; i++) | |
{ | |
printf("%1u", c[i]); | |
} | |
printf("\n\n"); | |
// Message encoding | |
uint8_t s[FT8_BIT_COUNT]; | |
ft8_encode(c, s); | |
// Print the 174 codeword 1-bit symbols for debugging | |
printf("Packed codeword, 1-bit symbols:\n"); | |
for(i = 0; i < FT8_BIT_COUNT; i++) | |
{ | |
printf("%1u", s[i]); | |
} | |
printf("\n\n"); | |
uint8_t o[FT8_ENCODE_COUNT]; | |
ft8_merge_sync_vector(s, o); | |
printf("%u Channel Symbols:\n", FT8_ENCODE_COUNT); | |
for(i = 0; i < FT8_ENCODE_COUNT; i++) | |
{ | |
printf("%1u", o[i]); | |
} | |
printf("\n\n"); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef GENERATOR_H | |
#define GENERATOR_H | |
#include <stdint.h> | |
const uint8_t generator_bits[83][12] = | |
{ | |
{0b10000011, 0b00101001, 0b11001110, 0b00010001, 0b10111111, 0b00110001, 0b11101010, 0b11110101, 0b00001001, 0b11110010, 0b01111111, 0b11000000}, | |
{0b01110110, 0b00011100, 0b00100110, 0b01001110, 0b00100101, 0b11000010, 0b01011001, 0b00110011, 0b01010100, 0b10010011, 0b00010011, 0b00100000}, | |
{0b11011100, 0b00100110, 0b01011001, 0b00000010, 0b11111011, 0b00100111, 0b01111100, 0b01100100, 0b00010000, 0b10100001, 0b10111101, 0b11000000}, | |
{0b00011011, 0b00111111, 0b01000001, 0b01111000, 0b01011000, 0b11001101, 0b00101101, 0b11010011, 0b00111110, 0b11000111, 0b11110110, 0b00100000}, | |
{0b00001001, 0b11111101, 0b10100100, 0b11111110, 0b11100000, 0b01000001, 0b10010101, 0b11111101, 0b00000011, 0b01000111, 0b10000011, 0b10100000}, | |
{0b00000111, 0b01111100, 0b11001100, 0b11000001, 0b00011011, 0b10001000, 0b01110011, 0b11101101, 0b01011100, 0b00111101, 0b01001000, 0b10100000}, | |
{0b00101001, 0b10110110, 0b00101010, 0b11111110, 0b00111100, 0b10100000, 0b00110110, 0b11110100, 0b11111110, 0b00011010, 0b10011101, 0b10100000}, | |
{0b01100000, 0b01010100, 0b11111010, 0b11110101, 0b11110011, 0b01011101, 0b10010110, 0b11010011, 0b10110000, 0b11001000, 0b11000011, 0b11100000}, | |
{0b11100010, 0b00000111, 0b10011000, 0b11100100, 0b00110001, 0b00001110, 0b11101101, 0b00100111, 0b10001000, 0b01001010, 0b11101001, 0b00000000}, | |
{0b01110111, 0b01011100, 0b10011100, 0b00001000, 0b11101000, 0b00001110, 0b00100110, 0b11011101, 0b10101110, 0b01010110, 0b00110001, 0b10000000}, | |
{0b10110000, 0b10111000, 0b00010001, 0b00000010, 0b10001100, 0b00101011, 0b11111001, 0b10010111, 0b00100001, 0b00110100, 0b10000111, 0b11000000}, | |
{0b00011000, 0b10100000, 0b11001001, 0b00100011, 0b00011111, 0b11000110, 0b00001010, 0b11011111, 0b01011100, 0b01011110, 0b10100011, 0b00100000}, | |
{0b01110110, 0b01000111, 0b00011110, 0b10000011, 0b00000010, 0b10100000, 0b01110010, 0b00011110, 0b00000001, 0b10110001, 0b00101011, 0b10000000}, | |
{0b11111111, 0b10111100, 0b11001011, 0b10000000, 0b11001010, 0b10000011, 0b01000001, 0b11111010, 0b11111011, 0b01000111, 0b10110010, 0b11100000}, | |
{0b01100110, 0b10100111, 0b00101010, 0b00010101, 0b10001111, 0b10010011, 0b00100101, 0b10100010, 0b10111111, 0b01100111, 0b00010111, 0b00000000}, | |
{0b11000100, 0b00100100, 0b00110110, 0b10001001, 0b11111110, 0b10000101, 0b10110001, 0b11000101, 0b00010011, 0b01100011, 0b10100001, 0b10000000}, | |
{0b00001101, 0b11111111, 0b01110011, 0b10010100, 0b00010100, 0b11010001, 0b10100001, 0b10110011, 0b01001011, 0b00011100, 0b00100111, 0b00000000}, | |
{0b00010101, 0b10110100, 0b10001000, 0b00110000, 0b01100011, 0b01101100, 0b10001011, 0b10011001, 0b10001001, 0b01001001, 0b01110010, 0b11100000}, | |
{0b00101001, 0b10101000, 0b10011100, 0b00001101, 0b00111101, 0b11101000, 0b00011101, 0b01100110, 0b01010100, 0b10001001, 0b10110000, 0b11100000}, | |
{0b01001111, 0b00010010, 0b01101111, 0b00110111, 0b11111010, 0b01010001, 0b11001011, 0b11100110, 0b00011011, 0b11010110, 0b10111001, 0b01000000}, | |
{0b10011001, 0b11000100, 0b01110010, 0b00111001, 0b11010000, 0b11011001, 0b01111101, 0b00111100, 0b10000100, 0b11100000, 0b10010100, 0b00000000}, | |
{0b00011001, 0b00011001, 0b10110111, 0b01010001, 0b00011001, 0b01110110, 0b01010110, 0b00100001, 0b10111011, 0b01001111, 0b00011110, 0b10000000}, | |
{0b00001001, 0b11011011, 0b00010010, 0b11010111, 0b00110001, 0b11111010, 0b11101110, 0b00001011, 0b10000110, 0b11011111, 0b01101011, 0b10000000}, | |
{0b01001000, 0b10001111, 0b11000011, 0b00111101, 0b11110100, 0b00111111, 0b10111101, 0b11101110, 0b10100100, 0b11101010, 0b11111011, 0b01000000}, | |
{0b10000010, 0b01110100, 0b00100011, 0b11101110, 0b01000000, 0b10110110, 0b01110101, 0b11110111, 0b01010110, 0b11101011, 0b01011111, 0b11100000}, | |
{0b10101011, 0b11100001, 0b10010111, 0b11000100, 0b10000100, 0b11001011, 0b01110100, 0b01110101, 0b01110001, 0b01000100, 0b10101001, 0b10100000}, | |
{0b00101011, 0b01010000, 0b00001110, 0b01001011, 0b11000000, 0b11101100, 0b01011010, 0b01101101, 0b00101011, 0b11011011, 0b11011101, 0b00000000}, | |
{0b11000100, 0b01110100, 0b10101010, 0b01010011, 0b11010111, 0b00000010, 0b00011000, 0b01110110, 0b00010110, 0b01101001, 0b00110110, 0b00000000}, | |
{0b10001110, 0b10111010, 0b00011010, 0b00010011, 0b11011011, 0b00110011, 0b10010000, 0b10111101, 0b01100111, 0b00011000, 0b11001110, 0b11000000}, | |
{0b01110101, 0b00111000, 0b01000100, 0b01100111, 0b00111010, 0b00100111, 0b01111000, 0b00101100, 0b11000100, 0b00100000, 0b00010010, 0b11100000}, | |
{0b00000110, 0b11111111, 0b10000011, 0b10100001, 0b01000101, 0b11000011, 0b01110000, 0b00110101, 0b10100101, 0b11000001, 0b00100110, 0b10000000}, | |
{0b00111011, 0b00110111, 0b01000001, 0b01111000, 0b01011000, 0b11001100, 0b00101101, 0b11010011, 0b00111110, 0b11000011, 0b11110110, 0b00100000}, | |
{0b10011010, 0b01001010, 0b01011010, 0b00101000, 0b11101110, 0b00010111, 0b11001010, 0b10011100, 0b00110010, 0b01001000, 0b01000010, 0b11000000}, | |
{0b10111100, 0b00101001, 0b11110100, 0b01100101, 0b00110000, 0b10011100, 0b10010111, 0b01111110, 0b10001001, 0b01100001, 0b00001010, 0b01000000}, | |
{0b00100110, 0b01100011, 0b10101110, 0b01101101, 0b11011111, 0b10001011, 0b01011100, 0b11100010, 0b10111011, 0b00101001, 0b01001000, 0b10000000}, | |
{0b01000110, 0b11110010, 0b00110001, 0b11101111, 0b11100100, 0b01010111, 0b00000011, 0b01001100, 0b00011000, 0b00010100, 0b01000001, 0b10000000}, | |
{0b00111111, 0b10110010, 0b11001110, 0b10000101, 0b10101011, 0b11101001, 0b10110000, 0b11000111, 0b00101110, 0b00000110, 0b11111011, 0b11100000}, | |
{0b11011110, 0b10000111, 0b01001000, 0b00011111, 0b00101000, 0b00101100, 0b00010101, 0b00111001, 0b01110001, 0b10100000, 0b10100010, 0b11100000}, | |
{0b11111100, 0b11010111, 0b11001100, 0b11110010, 0b00111100, 0b01101001, 0b11111010, 0b10011001, 0b10111011, 0b10100001, 0b01000001, 0b00100000}, | |
{0b11110000, 0b00100110, 0b00010100, 0b01000111, 0b11101001, 0b01001001, 0b00001100, 0b10101000, 0b11100100, 0b01110100, 0b11001110, 0b11000000}, | |
{0b01000100, 0b00010000, 0b00010001, 0b01011000, 0b00011000, 0b00011001, 0b01101111, 0b10010101, 0b11001101, 0b11010111, 0b00000001, 0b00100000}, | |
{0b00001000, 0b10001111, 0b11000011, 0b00011101, 0b11110100, 0b10111111, 0b10111101, 0b11100010, 0b10100100, 0b11101010, 0b11111011, 0b01000000}, | |
{0b10111000, 0b11111110, 0b11110001, 0b10110110, 0b00110000, 0b01110111, 0b00101001, 0b11111011, 0b00001010, 0b00000111, 0b10001100, 0b00000000}, | |
{0b01011010, 0b11111110, 0b10100111, 0b10101100, 0b11001100, 0b10110111, 0b01111011, 0b10111100, 0b10011101, 0b10011001, 0b10101001, 0b00000000}, | |
{0b01001001, 0b10100111, 0b00000001, 0b01101010, 0b11000110, 0b01010011, 0b11110110, 0b01011110, 0b11001101, 0b11001001, 0b00000111, 0b01100000}, | |
{0b00011001, 0b01000100, 0b11010000, 0b10000101, 0b10111110, 0b01001110, 0b01111101, 0b10101000, 0b11010110, 0b11001100, 0b01111101, 0b00000000}, | |
{0b00100101, 0b00011111, 0b01100010, 0b10101101, 0b11000100, 0b00000011, 0b00101111, 0b00001110, 0b11100111, 0b00010100, 0b00000000, 0b00100000}, | |
{0b01010110, 0b01000111, 0b00011111, 0b10000111, 0b00000010, 0b10100000, 0b01110010, 0b00011110, 0b00000000, 0b10110001, 0b00101011, 0b10000000}, | |
{0b00101011, 0b10001110, 0b01001001, 0b00100011, 0b11110010, 0b11011101, 0b01010001, 0b11100010, 0b11010101, 0b00110111, 0b11111010, 0b00000000}, | |
{0b01101011, 0b01010101, 0b00001010, 0b01000000, 0b10100110, 0b01101111, 0b01000111, 0b01010101, 0b11011110, 0b10010101, 0b11000010, 0b01100000}, | |
{0b10100001, 0b10001010, 0b11010010, 0b10001101, 0b01001110, 0b00100111, 0b11111110, 0b10010010, 0b10100100, 0b11110110, 0b11001000, 0b01000000}, | |
{0b00010000, 0b11000010, 0b11100101, 0b10000110, 0b00111000, 0b10001100, 0b10111000, 0b00101010, 0b00111101, 0b10000000, 0b01110101, 0b10000000}, | |
{0b11101111, 0b00110100, 0b10100100, 0b00011000, 0b00010111, 0b11101110, 0b00000010, 0b00010011, 0b00111101, 0b10110010, 0b11101011, 0b00000000}, | |
{0b01111110, 0b10011100, 0b00001100, 0b01010100, 0b00110010, 0b01011010, 0b10011100, 0b00010101, 0b10000011, 0b01101110, 0b00000000, 0b00000000}, | |
{0b00110110, 0b10010011, 0b11100101, 0b01110010, 0b11010001, 0b11111101, 0b11100100, 0b11001101, 0b11110000, 0b01111001, 0b11101000, 0b01100000}, | |
{0b10111111, 0b10110010, 0b11001110, 0b11000101, 0b10101011, 0b11100001, 0b10110000, 0b11000111, 0b00101110, 0b00000111, 0b11111011, 0b11100000}, | |
{0b01111110, 0b11100001, 0b10000010, 0b00110000, 0b11000101, 0b10000011, 0b11001100, 0b11001100, 0b01010111, 0b11010100, 0b10110000, 0b10000000}, | |
{0b10100000, 0b01100110, 0b11001011, 0b00101111, 0b11101101, 0b10101111, 0b11001001, 0b11110101, 0b00100110, 0b01100100, 0b00010010, 0b01100000}, | |
{0b10111011, 0b00100011, 0b01110010, 0b01011010, 0b10111100, 0b01000111, 0b11001100, 0b01011111, 0b01001100, 0b11000100, 0b11001101, 0b00100000}, | |
{0b11011110, 0b11011001, 0b11011011, 0b10100011, 0b10111110, 0b11100100, 0b00001100, 0b01011001, 0b10110101, 0b01100000, 0b10011011, 0b01000000}, | |
{0b11011001, 0b10100111, 0b00000001, 0b01101010, 0b11000110, 0b01010011, 0b11100110, 0b11011110, 0b11001101, 0b11001001, 0b00000011, 0b01100000}, | |
{0b10011010, 0b11010100, 0b01101010, 0b11101101, 0b01011111, 0b01110000, 0b01111111, 0b00101000, 0b00001010, 0b10110101, 0b11111100, 0b01000000}, | |
{0b11100101, 0b10010010, 0b00011100, 0b01110111, 0b10000010, 0b00100101, 0b10000111, 0b00110001, 0b01101101, 0b01111101, 0b00111100, 0b00100000}, | |
{0b01001111, 0b00010100, 0b11011010, 0b10000010, 0b01000010, 0b10101000, 0b10111000, 0b01101101, 0b11001010, 0b01110011, 0b00110101, 0b00100000}, | |
{0b10001011, 0b10001011, 0b01010000, 0b01111010, 0b11010100, 0b01100111, 0b11010100, 0b01000100, 0b00011101, 0b11110111, 0b01110000, 0b11100000}, | |
{0b00100010, 0b10000011, 0b00011100, 0b10011100, 0b11110001, 0b00010110, 0b10010100, 0b01100111, 0b10101101, 0b00000100, 0b10110110, 0b10000000}, | |
{0b00100001, 0b00111011, 0b10000011, 0b10001111, 0b11100010, 0b10101110, 0b01010100, 0b11000011, 0b10001110, 0b11100111, 0b00011000, 0b00000000}, | |
{0b01011101, 0b10010010, 0b01101011, 0b01101101, 0b11010111, 0b00011111, 0b00001000, 0b01010001, 0b10000001, 0b10100100, 0b11100001, 0b00100000}, | |
{0b01100110, 0b10101011, 0b01111001, 0b11010100, 0b10110010, 0b10011110, 0b11100110, 0b11100110, 0b10010101, 0b00001001, 0b11100101, 0b01100000}, | |
{0b10010101, 0b10000001, 0b01001000, 0b01101000, 0b00101101, 0b01110100, 0b10001010, 0b00111000, 0b11011101, 0b01101000, 0b10111010, 0b10100000}, | |
{0b10111000, 0b11001110, 0b00000010, 0b00001100, 0b11110000, 0b01101001, 0b11000011, 0b00101010, 0b01110010, 0b00111010, 0b10110001, 0b01000000}, | |
{0b11110100, 0b00110011, 0b00011101, 0b01101101, 0b01000110, 0b00010110, 0b00000111, 0b11101001, 0b01010111, 0b01010010, 0b01110100, 0b01100000}, | |
{0b01101101, 0b10100010, 0b00111011, 0b10100100, 0b00100100, 0b10111001, 0b01011001, 0b01100001, 0b00110011, 0b11001111, 0b10011100, 0b10000000}, | |
{0b10100110, 0b00110110, 0b10111100, 0b10111100, 0b01111011, 0b00110000, 0b11000101, 0b11111011, 0b11101010, 0b11100110, 0b01111111, 0b11100000}, | |
{0b01011100, 0b10110000, 0b11011000, 0b01101010, 0b00000111, 0b11011111, 0b01100101, 0b01001010, 0b10010000, 0b10001001, 0b10100010, 0b00000000}, | |
{0b11110001, 0b00011111, 0b00010000, 0b01101000, 0b01001000, 0b01111000, 0b00001111, 0b11001001, 0b11101100, 0b11011101, 0b10000000, 0b10100000}, | |
{0b00011111, 0b10111011, 0b01010011, 0b01100100, 0b11111011, 0b10001101, 0b00101100, 0b10011101, 0b01110011, 0b00001101, 0b01011011, 0b10100000}, | |
{0b11111100, 0b10111000, 0b01101011, 0b11000111, 0b00001010, 0b01010000, 0b11001001, 0b11010000, 0b00101010, 0b01011101, 0b00000011, 0b01000000}, | |
{0b10100101, 0b00110100, 0b01000011, 0b00110000, 0b00101001, 0b11101010, 0b11000001, 0b01011111, 0b00110010, 0b00101110, 0b00110100, 0b11000000}, | |
{0b11001001, 0b10001001, 0b11011001, 0b11000111, 0b11000011, 0b11010011, 0b10111000, 0b11000101, 0b01011101, 0b01110101, 0b00010011, 0b00000000}, | |
{0b01111011, 0b10110011, 0b10001011, 0b00101111, 0b00000001, 0b10000110, 0b11010100, 0b01100110, 0b01000011, 0b10101110, 0b10010110, 0b00100000}, | |
{0b00100110, 0b01000100, 0b11101011, 0b10101101, 0b11101011, 0b01000100, 0b10111001, 0b01000110, 0b01111101, 0b00011111, 0b01000010, 0b11000000}, | |
{0b01100000, 0b10001100, 0b11001000, 0b01010111, 0b01011001, 0b01001011, 0b11111011, 0b10110101, 0b01011101, 0b01101001, 0b01100000, 0b00000000} | |
}; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment