Skip to content

Instantly share code, notes, and snippets.

@NT7S
Last active June 5, 2022 13:32
Show Gist options
  • Save NT7S/6e38d8a35d153f015d476bc49b40effb to your computer and use it in GitHub Desktop.
Save NT7S/6e38d8a35d153f015d476bc49b40effb to your computer and use it in GitHub Desktop.
FT8 Encoding test script
/**
* \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;
}
/**
* \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 */
#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;
}
#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