bugfix and correct encode/decode for RS 52,30,23, 46,26,21, 45,26,20, 44,16,29; implement catch2 cases for P25 Phase 2 RS codes; correct bad EC check for RS 24,12,13, 24,16,9 and 36,20,17 that could cause false positive failures in edge case conditions;

r05a04_dev
Bryan Biedenkapp 3 weeks ago
parent ff0fbec629
commit d51f4fc4a4

@ -5,7 +5,7 @@
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* Copyright (C) 2016 Jonathan Naylor, G4KLX * Copyright (C) 2016 Jonathan Naylor, G4KLX
* Copyright (C) 2017,2023,2025 Bryan Biedenkapp, N2PLL * Copyright (C) 2017,2023,2025,2026 Bryan Biedenkapp, N2PLL
* *
*/ */
#include "Defines.h" #include "Defines.h"
@ -23,6 +23,8 @@ using namespace edac;
// Constants // Constants
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Project 25 Phase I Reed-Solomon (TIA-102.BAAA-B Section 4.9) */
const uint8_t ENCODE_MATRIX[12U][24U] = { const uint8_t ENCODE_MATRIX[12U][24U] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 062, 044, 003, 025, 014, 016, 027, 003, 053, 004, 036, 047 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 062, 044, 003, 025, 014, 016, 027, 003, 053, 004, 036, 047 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 011, 012, 011, 011, 016, 064, 067, 055, 001, 076, 026, 073 }, { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 011, 012, 011, 011, 016, 064, 067, 055, 001, 076, 026, 073 },
@ -77,6 +79,8 @@ const uint8_t ENCODE_MATRIX_362017[20U][36U] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 002, 001, 053, 074, 002, 014, 052, 074, 012, 057, 024, 063, 015, 042, 052, 033 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 002, 001, 053, 074, 002, 014, 052, 074, 012, 057, 024, 063, 015, 042, 052, 033 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 034, 035, 002, 023, 021, 027, 022, 033, 064, 042, 005, 073, 051, 046, 073, 060 } }; { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 034, 035, 002, 023, 021, 027, 022, 033, 064, 042, 005, 073, 051, 046, 073, 060 } };
/** Project 25 Phase II Reed-Solomon (TIA-102.BBAC-A Section 5.6) */
const uint8_t ENCODE_MATRIX_633529[35U][63U] = { const uint8_t ENCODE_MATRIX_633529[35U][63U] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 013, 014, 023, 076, 015, 077, 050, 062, 015, 014, 012, 007, 074, 045, 023, 071, 050, 064, 010, 016, 022, 071, 077, 020, 051, 061, 032, 006 }, { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 013, 014, 023, 076, 015, 077, 050, 062, 015, 014, 012, 007, 074, 045, 023, 071, 050, 064, 010, 016, 022, 071, 077, 020, 051, 061, 032, 006 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 072, 043, 045, 021, 020, 011, 012, 002, 034, 045, 060, 030, 011, 047, 014, 003, 014, 026, 004, 054, 041, 002, 075, 034, 043, 011, 056, 016 }, { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 072, 043, 045, 021, 020, 011, 012, 002, 034, 045, 060, 030, 011, 047, 014, 003, 014, 026, 004, 054, 041, 002, 075, 034, 043, 011, 056, 016 },
@ -115,110 +119,110 @@ const uint8_t ENCODE_MATRIX_633529[35U][63U] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 026, 055, 065, 012, 051, 067, 043, 012, 026, 035, 027, 015, 075, 055, 042, 067, 050, 045, 056, 061, 042, 051, 011, 053, 007, 024, 013, 034 } }; { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 026, 055, 065, 012, 051, 067, 043, 012, 026, 035, 027, 015, 075, 055, 042, 067, 050, 045, 056, 061, 042, 051, 011, 053, 007, 024, 013, 034 } };
const uint8_t ENCODE_MATRIX_523023[30U][52U] = { const uint8_t ENCODE_MATRIX_523023[30U][52U] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 023, 076, 015, 077, 050, 062, 015, 014, 012, 007, 074, 045, 023, 071, 050, 064, 010, 016, 022, 071, 077, 020 }, { 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 003, 011, 061, 045, 002, 035, 037, 016, 072, 003, 044, 011, 074, 020, 073, 024, 072, 053, 064, 070, 056, 063 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 045, 021, 020, 011, 012, 002, 034, 045, 060, 030, 011, 047, 014, 003, 014, 026, 004, 054, 041, 002, 075, 034 }, { 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 037, 073, 045, 031, 046, 021, 013, 017, 015, 002, 047, 003, 024, 051, 074, 064, 002, 066, 072, 071, 057, 041 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 024, 036, 024, 045, 063, 072, 007, 027, 012, 032, 077, 066, 020, 035, 071, 030, 045, 023, 025, 060, 067, 030 }, { 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 022, 034, 057, 013, 053, 071, 033, 046, 075, 016, 041, 066, 014, 054, 075, 003, 076, 017, 064, 030, 034, 020 },
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 011, 022, 057, 030, 071, 016, 013, 074, 020, 074, 010, 022, 016, 040, 001, 070, 013, 012, 041, 045, 074, 021 }, { 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 022, 021, 010, 001, 071, 064, 063, 066, 024, 076, 055, 060, 071, 064, 070, 002, 011, 063, 015, 026, 075, 043 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 071, 034, 045, 005, 050, 044, 071, 003, 060, 053, 024, 017, 061, 040, 020, 030, 011, 076, 026, 017, 017, 035 }, { 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 024, 046, 056, 036, 017, 025, 012, 021, 070, 040, 020, 015, 021, 011, 013, 016, 074, 061, 052, 016, 023, 013 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 061, 045, 002, 035, 037, 016, 072, 003, 044, 011, 074, 020, 073, 024, 072, 053, 064, 070, 056, 063, 067, 024 }, { 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 011, 064, 054, 071, 007, 041, 020, 075, 010, 030, 020, 071, 053, 015, 003, 065, 013, 033, 060, 073, 075, 055 },
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 045, 031, 046, 021, 013, 017, 015, 002, 047, 003, 024, 051, 074, 064, 002, 066, 072, 071, 057, 041, 040, 025 }, { 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 034, 013, 054, 030, 044, 054, 055, 046, 040, 012, 033, 016, 063, 072, 025, 051, 071, 074, 046, 014, 074, 027 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 057, 013, 053, 071, 033, 046, 075, 016, 041, 066, 014, 054, 075, 003, 076, 017, 064, 030, 034, 020, 076, 044 }, { 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 035, 010, 076, 055, 017, 046, 027, 070, 061, 064, 024, 022, 011, 037, 017, 035, 022, 046, 044, 064, 072, 064 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 010, 001, 071, 064, 063, 066, 024, 076, 055, 060, 071, 064, 070, 002, 011, 063, 015, 026, 075, 043, 017, 072 }, { 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 022, 036, 034, 020, 037, 020, 054, 072, 012, 062, 027, 005, 035, 061, 013, 060, 027, 037, 044, 006, 021, 005 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 056, 036, 017, 025, 012, 021, 070, 040, 020, 015, 021, 011, 013, 016, 074, 061, 052, 016, 023, 013, 017, 075 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 055, 064, 074, 024, 056, 017, 001, 002, 004, 054, 007, 034, 075, 062, 023, 010, 041, 052, 032, 062, 074, 022 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 054, 071, 007, 041, 020, 075, 010, 030, 020, 071, 053, 015, 003, 065, 013, 033, 060, 073, 075, 055, 045, 015 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 024, 031, 013, 052, 032, 002, 061, 043, 014, 060, 002, 047, 075, 015, 015, 045, 066, 031, 063, 031, 067, 012 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 054, 030, 044, 054, 055, 046, 040, 012, 033, 016, 063, 072, 025, 051, 071, 074, 046, 014, 074, 027, 006, 034 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 056, 010, 017, 037, 012, 062, 011, 071, 003, 020, 042, 060, 010, 026, 033, 053, 056, 060, 060, 024, 063, 021 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 076, 055, 017, 046, 027, 070, 061, 064, 024, 022, 011, 037, 017, 035, 022, 046, 044, 064, 072, 064, 025, 066 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 046, 004, 071, 071, 054, 045, 013, 025, 012, 051, 057, 056, 064, 002, 047, 041, 022, 047, 075, 050, 074, 011 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 034, 020, 037, 020, 054, 072, 012, 062, 027, 005, 035, 061, 013, 060, 027, 037, 044, 006, 021, 005, 053, 021 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 044, 040, 054, 046, 036, 022, 061, 022, 062, 014, 054, 015, 060, 007, 052, 032, 065, 010, 043, 072, 041, 001 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 074, 024, 056, 017, 001, 002, 004, 054, 007, 034, 075, 062, 023, 010, 041, 052, 032, 062, 074, 022, 025, 041 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 067, 067, 061, 050, 071, 026, 073, 046, 015, 041, 067, 010, 021, 006, 026, 012, 063, 012, 053, 050, 047, 001 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 013, 052, 032, 002, 061, 043, 014, 060, 002, 047, 075, 015, 015, 045, 066, 031, 063, 031, 067, 012, 076, 047 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 026, 057, 021, 016, 062, 004, 005, 034, 074, 025, 065, 071, 063, 030, 040, 047, 031, 030, 032, 067, 014, 026 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 017, 037, 012, 062, 011, 071, 003, 020, 042, 060, 010, 026, 033, 053, 056, 060, 060, 024, 063, 021, 042, 057 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 054, 046, 040, 054, 072, 013, 042, 010, 050, 014, 075, 051, 014, 041, 027, 001, 001, 014, 070, 042, 074, 055 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 071, 071, 054, 045, 013, 025, 012, 051, 057, 056, 064, 002, 047, 041, 022, 047, 075, 050, 074, 011, 076, 070 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 071, 076, 073, 076, 034, 006, 044, 056, 070, 072, 027, 026, 060, 023, 074, 042, 056, 004, 020, 055, 035, 011 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 054, 046, 036, 022, 061, 022, 062, 014, 054, 015, 060, 007, 052, 032, 065, 010, 043, 072, 041, 001, 067, 066 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 066, 074, 002, 012, 053, 075, 030, 020, 073, 075, 034, 044, 007, 073, 057, 076, 074, 071, 002, 065, 001, 037 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 061, 050, 071, 026, 073, 046, 015, 041, 067, 010, 021, 006, 026, 012, 063, 012, 053, 050, 047, 001, 011, 062 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 071, 044, 041, 034, 072, 027, 022, 024, 040, 051, 046, 067, 075, 030, 046, 032, 021, 071, 045, 027, 012, 064 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 021, 016, 062, 004, 005, 034, 074, 025, 065, 071, 063, 030, 040, 047, 031, 030, 032, 067, 014, 026, 074, 051 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 013, 065, 067, 037, 021, 005, 077, 040, 031, 054, 043, 041, 013, 030, 013, 037, 062, 045, 061, 053, 005, 063 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 040, 054, 072, 013, 042, 010, 050, 014, 075, 051, 014, 041, 027, 001, 001, 014, 070, 042, 074, 055, 057, 077 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 053, 032, 074, 007, 035, 062, 040, 036, 042, 010, 024, 031, 067, 054, 021, 001, 072, 072, 073, 006, 061, 017 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 073, 076, 034, 006, 044, 056, 070, 072, 027, 026, 060, 023, 074, 042, 056, 004, 020, 055, 035, 011, 021, 027 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 035, 077, 057, 075, 020, 037, 011, 065, 011, 066, 026, 035, 036, 033, 031, 031, 072, 045, 042, 051, 060, 071 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 002, 012, 053, 075, 030, 020, 073, 075, 034, 044, 007, 073, 057, 076, 074, 071, 002, 065, 001, 037, 050, 035 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 005, 020, 040, 013, 037, 033, 061, 040, 027, 004, 034, 036, 044, 022, 004, 065, 067, 064, 022, 062, 031, 034 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 041, 034, 072, 027, 022, 024, 040, 051, 046, 067, 075, 030, 046, 032, 021, 071, 045, 027, 012, 064, 043, 020 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 003, 077, 044, 074, 025, 047, 001, 027, 076, 055, 043, 045, 011, 040, 046, 041, 057, 014, 030, 043, 042, 074 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 067, 037, 021, 005, 077, 040, 031, 054, 043, 041, 013, 030, 013, 037, 062, 045, 061, 053, 005, 063, 013, 063 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 052, 004, 033, 041, 064, 037, 065, 003, 037, 071, 010, 016, 076, 023, 004, 016, 063, 017, 067, 001, 010, 012 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 074, 007, 035, 062, 040, 036, 042, 010, 024, 031, 067, 054, 021, 001, 072, 072, 073, 006, 061, 017, 020, 067 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 015, 021, 074, 035, 020, 070, 003, 010, 062, 044, 076, 076, 034, 023, 053, 064, 022, 062, 034, 030, 063, 070 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 057, 075, 020, 037, 011, 065, 011, 066, 026, 035, 036, 033, 031, 031, 072, 045, 042, 051, 060, 071, 015, 040 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 054, 075, 036, 001, 051, 051, 036, 016, 074, 002, 014, 042, 013, 016, 034, 012, 022, 007, 022, 044, 023, 022 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 040, 013, 037, 033, 061, 040, 027, 004, 034, 036, 044, 022, 004, 065, 067, 064, 022, 062, 031, 034, 062, 040 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 065, 023, 065, 063, 012, 060, 055, 014, 005, 003, 003, 006, 044, 004, 006, 073, 016, 076, 055, 006, 030, 064 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 044, 074, 025, 047, 001, 027, 076, 055, 043, 045, 011, 040, 046, 041, 057, 014, 030, 043, 042, 074, 044, 051 } }; { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 026, 055, 065, 012, 051, 067, 043, 012, 026, 035, 027, 015, 075, 055, 042, 067, 050, 045, 056, 061, 042, 051 } };
const uint8_t ENCODE_MATRIX_462621[26U][46U] = { const uint8_t ENCODE_MATRIX_462621[26U][46U] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 055, 043, 012, 026, 035, 027, 015, 075, 055, 042, 067, 050, 045, 056, 061, 042, 051, 011, 053, 007 }, { 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 024, 046, 056, 036, 017, 025, 012, 021, 070, 040, 020, 015, 021, 011, 013, 016, 074, 061, 052, 016 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 014, 012, 007, 074, 045, 023, 071, 050, 064, 010, 016, 022, 071, 077, 020, 021, 020, 011, 012, 002 }, { 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 011, 064, 054, 071, 007, 041, 020, 075, 010, 030, 020, 071, 053, 015, 003, 065, 013, 033, 060, 073 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 060, 030, 011, 047, 014, 003, 014, 026, 004, 054, 041, 002, 075, 034, 036, 024, 045, 063, 072, 007 }, { 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 034, 013, 054, 030, 044, 054, 055, 046, 040, 012, 033, 016, 063, 072, 025, 051, 071, 074, 046, 014 },
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 012, 032, 077, 066, 020, 035, 071, 030, 045, 023, 025, 060, 067, 030, 022, 057, 030, 071, 016, 013 }, { 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 035, 010, 076, 055, 017, 046, 027, 070, 061, 064, 024, 022, 011, 037, 017, 035, 022, 046, 044, 064 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 020, 074, 010, 022, 016, 040, 001, 070, 013, 012, 041, 045, 074, 021, 034, 045, 005, 050, 044, 071 }, { 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 022, 036, 034, 020, 037, 020, 054, 072, 012, 062, 027, 005, 035, 061, 013, 060, 027, 037, 044, 006 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 060, 053, 024, 017, 061, 040, 020, 030, 011, 076, 026, 017, 017, 035, 045, 002, 035, 037, 016, 072 }, { 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 055, 064, 074, 024, 056, 017, 001, 002, 004, 054, 007, 034, 075, 062, 023, 010, 041, 052, 032, 062 },
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 044, 011, 074, 020, 073, 024, 072, 053, 064, 070, 056, 063, 067, 024, 031, 046, 021, 013, 017, 015 }, { 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 024, 031, 013, 052, 032, 002, 061, 043, 014, 060, 002, 047, 075, 015, 015, 045, 066, 031, 063, 031 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 047, 003, 024, 051, 074, 064, 002, 066, 072, 071, 057, 041, 040, 025, 013, 053, 071, 033, 046, 075 }, { 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 056, 010, 017, 037, 012, 062, 011, 071, 003, 020, 042, 060, 010, 026, 033, 053, 056, 060, 060, 024 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 041, 066, 014, 054, 075, 003, 076, 017, 064, 030, 034, 020, 076, 044, 001, 071, 064, 063, 066, 024 }, { 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 046, 004, 071, 071, 054, 045, 013, 025, 012, 051, 057, 056, 064, 002, 047, 041, 022, 047, 075, 050 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 055, 060, 071, 064, 070, 002, 011, 063, 015, 026, 075, 043, 017, 072, 036, 017, 025, 012, 021, 070 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 044, 040, 054, 046, 036, 022, 061, 022, 062, 014, 054, 015, 060, 007, 052, 032, 065, 010, 043, 072 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 020, 015, 021, 011, 013, 016, 074, 061, 052, 016, 023, 013, 017, 075, 071, 007, 041, 020, 075, 010 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 067, 067, 061, 050, 071, 026, 073, 046, 015, 041, 067, 010, 021, 006, 026, 012, 063, 012, 053, 050 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 020, 071, 053, 015, 003, 065, 013, 033, 060, 073, 075, 055, 045, 015, 030, 044, 054, 055, 046, 040 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 026, 057, 021, 016, 062, 004, 005, 034, 074, 025, 065, 071, 063, 030, 040, 047, 031, 030, 032, 067 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 033, 016, 063, 072, 025, 051, 071, 074, 046, 014, 074, 027, 006, 034, 055, 017, 046, 027, 070, 061 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 054, 046, 040, 054, 072, 013, 042, 010, 050, 014, 075, 051, 014, 041, 027, 001, 001, 014, 070, 042 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 024, 022, 011, 037, 017, 035, 022, 046, 044, 064, 072, 064, 025, 066, 020, 037, 020, 054, 072, 012 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 071, 076, 073, 076, 034, 006, 044, 056, 070, 072, 027, 026, 060, 023, 074, 042, 056, 004, 020, 055 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 027, 005, 035, 061, 013, 060, 027, 037, 044, 006, 021, 005, 053, 021, 024, 056, 017, 001, 002, 004 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 066, 074, 002, 012, 053, 075, 030, 020, 073, 075, 034, 044, 007, 073, 057, 076, 074, 071, 002, 065 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 007, 034, 075, 062, 023, 010, 041, 052, 032, 062, 074, 022, 025, 041, 052, 032, 002, 061, 043, 014 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 071, 044, 041, 034, 072, 027, 022, 024, 040, 051, 046, 067, 075, 030, 046, 032, 021, 071, 045, 027 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 002, 047, 075, 015, 015, 045, 066, 031, 063, 031, 067, 012, 076, 047, 037, 012, 062, 011, 071, 003 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 013, 065, 067, 037, 021, 005, 077, 040, 031, 054, 043, 041, 013, 030, 013, 037, 062, 045, 061, 053 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 042, 060, 010, 026, 033, 053, 056, 060, 060, 024, 063, 021, 042, 057, 071, 054, 045, 013, 025, 012 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 053, 032, 074, 007, 035, 062, 040, 036, 042, 010, 024, 031, 067, 054, 021, 001, 072, 072, 073, 006 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 057, 056, 064, 002, 047, 041, 022, 047, 075, 050, 074, 011, 076, 070, 046, 036, 022, 061, 022, 062 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 035, 077, 057, 075, 020, 037, 011, 065, 011, 066, 026, 035, 036, 033, 031, 031, 072, 045, 042, 051 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 054, 015, 060, 007, 052, 032, 065, 010, 043, 072, 041, 001, 067, 066, 050, 071, 026, 073, 046, 015 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 005, 020, 040, 013, 037, 033, 061, 040, 027, 004, 034, 036, 044, 022, 004, 065, 067, 064, 022, 062 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 067, 010, 021, 006, 026, 012, 063, 012, 053, 050, 047, 001, 011, 062, 016, 062, 004, 005, 034, 074 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 003, 077, 044, 074, 025, 047, 001, 027, 076, 055, 043, 045, 011, 040, 046, 041, 057, 014, 030, 043 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 065, 071, 063, 030, 040, 047, 031, 030, 032, 067, 014, 026, 074, 051, 054, 072, 013, 042, 010, 050 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 052, 004, 033, 041, 064, 037, 065, 003, 037, 071, 010, 016, 076, 023, 004, 016, 063, 017, 067, 001 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 075, 051, 014, 041, 027, 001, 001, 014, 070, 042, 074, 055, 057, 077, 076, 034, 006, 044, 056, 070 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 015, 021, 074, 035, 020, 070, 003, 010, 062, 044, 076, 076, 034, 023, 053, 064, 022, 062, 034, 030 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 027, 026, 060, 023, 074, 042, 056, 004, 020, 055, 035, 011, 021, 027, 012, 053, 075, 030, 020, 073 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 054, 075, 036, 001, 051, 051, 036, 016, 074, 002, 014, 042, 013, 016, 034, 012, 022, 007, 022, 044 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 034, 044, 007, 073, 057, 076, 074, 071, 002, 065, 001, 037, 050, 035, 034, 072, 027, 022, 024, 040 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 065, 023, 065, 063, 012, 060, 055, 014, 005, 003, 003, 006, 044, 004, 006, 073, 016, 076, 055, 006 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 046, 067, 075, 030, 046, 032, 021, 071, 045, 027, 012, 064, 043, 020, 037, 021, 005, 077, 040, 031 } }; { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 026, 055, 065, 012, 051, 067, 043, 012, 026, 035, 027, 015, 075, 055, 042, 067, 050, 045, 056, 061 } };
const uint8_t ENCODE_MATRIX_452620[26U][45U] = { const uint8_t ENCODE_MATRIX_452620[26U][45U] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 012, 026, 035, 027, 015, 075, 055, 042, 067, 050, 045, 056, 061, 042, 051, 011, 053, 007, 024 }, { 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 024, 046, 056, 036, 017, 025, 012, 021, 070, 040, 020, 015, 021, 011, 013, 016, 074, 061, 052 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 007, 074, 045, 023, 071, 050, 064, 010, 016, 022, 071, 077, 020, 021, 020, 011, 012, 002, 034 }, { 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 011, 064, 054, 071, 007, 041, 020, 075, 010, 030, 020, 071, 053, 015, 003, 065, 013, 033, 060 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 030, 011, 047, 014, 003, 014, 026, 004, 054, 041, 002, 075, 034, 036, 024, 045, 063, 072, 007 }, { 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 034, 013, 054, 030, 044, 054, 055, 046, 040, 012, 033, 016, 063, 072, 025, 051, 071, 074, 046 },
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 032, 077, 066, 020, 035, 071, 030, 045, 023, 025, 060, 067, 030, 022, 057, 030, 071, 016, 013 }, { 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 035, 010, 076, 055, 017, 046, 027, 070, 061, 064, 024, 022, 011, 037, 017, 035, 022, 046, 044 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 074, 010, 022, 016, 040, 001, 070, 013, 012, 041, 045, 074, 021, 034, 045, 005, 050, 044, 071 }, { 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 022, 036, 034, 020, 037, 020, 054, 072, 012, 062, 027, 005, 035, 061, 013, 060, 027, 037, 044 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 053, 024, 017, 061, 040, 020, 030, 011, 076, 026, 017, 017, 035, 045, 002, 035, 037, 016, 072 }, { 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 055, 064, 074, 024, 056, 017, 001, 002, 004, 054, 007, 034, 075, 062, 023, 010, 041, 052, 032 },
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 011, 074, 020, 073, 024, 072, 053, 064, 070, 056, 063, 067, 024, 031, 046, 021, 013, 017, 015 }, { 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 024, 031, 013, 052, 032, 002, 061, 043, 014, 060, 002, 047, 075, 015, 015, 045, 066, 031, 063 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 003, 024, 051, 074, 064, 002, 066, 072, 071, 057, 041, 040, 025, 013, 053, 071, 033, 046, 075 }, { 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 056, 010, 017, 037, 012, 062, 011, 071, 003, 020, 042, 060, 010, 026, 033, 053, 056, 060, 060 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 066, 014, 054, 075, 003, 076, 017, 064, 030, 034, 020, 076, 044, 001, 071, 064, 063, 066, 024 }, { 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 046, 004, 071, 071, 054, 045, 013, 025, 012, 051, 057, 056, 064, 002, 047, 041, 022, 047, 075 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 060, 071, 064, 070, 002, 011, 063, 015, 026, 075, 043, 017, 072, 036, 017, 025, 012, 021, 070 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 044, 040, 054, 046, 036, 022, 061, 022, 062, 014, 054, 015, 060, 007, 052, 032, 065, 010, 043 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 015, 021, 011, 013, 016, 074, 061, 052, 016, 023, 013, 017, 075, 071, 007, 041, 020, 075, 010 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 067, 067, 061, 050, 071, 026, 073, 046, 015, 041, 067, 010, 021, 006, 026, 012, 063, 012, 053 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 071, 053, 015, 003, 065, 013, 033, 060, 073, 075, 055, 045, 015, 030, 044, 054, 055, 046, 040 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 026, 057, 021, 016, 062, 004, 005, 034, 074, 025, 065, 071, 063, 030, 040, 047, 031, 030, 032 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 016, 063, 072, 025, 051, 071, 074, 046, 014, 074, 027, 006, 034, 055, 017, 046, 027, 070, 061 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 054, 046, 040, 054, 072, 013, 042, 010, 050, 014, 075, 051, 014, 041, 027, 001, 001, 014, 070 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 022, 011, 037, 017, 035, 022, 046, 044, 064, 072, 064, 025, 066, 020, 037, 020, 054, 072, 012 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 071, 076, 073, 076, 034, 006, 044, 056, 070, 072, 027, 026, 060, 023, 074, 042, 056, 004, 020 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 005, 035, 061, 013, 060, 027, 037, 044, 006, 021, 005, 053, 021, 024, 056, 017, 001, 002, 004 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 066, 074, 002, 012, 053, 075, 030, 020, 073, 075, 034, 044, 007, 073, 057, 076, 074, 071, 002 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 034, 075, 062, 023, 010, 041, 052, 032, 062, 074, 022, 025, 041, 052, 032, 002, 061, 043, 014 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 071, 044, 041, 034, 072, 027, 022, 024, 040, 051, 046, 067, 075, 030, 046, 032, 021, 071, 045 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 047, 075, 015, 015, 045, 066, 031, 063, 031, 067, 012, 076, 047, 037, 012, 062, 011, 071, 003 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 013, 065, 067, 037, 021, 005, 077, 040, 031, 054, 043, 041, 013, 030, 013, 037, 062, 045, 061 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 060, 010, 026, 033, 053, 056, 060, 060, 024, 063, 021, 042, 057, 071, 054, 045, 013, 025, 012 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 053, 032, 074, 007, 035, 062, 040, 036, 042, 010, 024, 031, 067, 054, 021, 001, 072, 072, 073 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 056, 064, 002, 047, 041, 022, 047, 075, 050, 074, 011, 076, 070, 046, 036, 022, 061, 022, 062 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 035, 077, 057, 075, 020, 037, 011, 065, 011, 066, 026, 035, 036, 033, 031, 031, 072, 045, 042 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 015, 060, 007, 052, 032, 065, 010, 043, 072, 041, 001, 067, 066, 050, 071, 026, 073, 046, 015 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 005, 020, 040, 013, 037, 033, 061, 040, 027, 004, 034, 036, 044, 022, 004, 065, 067, 064, 022 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 010, 021, 006, 026, 012, 063, 012, 053, 050, 047, 001, 011, 062, 016, 062, 004, 005, 034, 074 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 003, 077, 044, 074, 025, 047, 001, 027, 076, 055, 043, 045, 011, 040, 046, 041, 057, 014, 030 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 071, 063, 030, 040, 047, 031, 030, 032, 067, 014, 026, 074, 051, 054, 072, 013, 042, 010, 050 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 052, 004, 033, 041, 064, 037, 065, 003, 037, 071, 010, 016, 076, 023, 004, 016, 063, 017, 067 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 051, 014, 041, 027, 001, 001, 014, 070, 042, 074, 055, 057, 077, 076, 034, 006, 044, 056, 070 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 015, 021, 074, 035, 020, 070, 003, 010, 062, 044, 076, 076, 034, 023, 053, 064, 022, 062, 034 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 026, 060, 023, 074, 042, 056, 004, 020, 055, 035, 011, 021, 027, 012, 053, 075, 030, 020, 073 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 054, 075, 036, 001, 051, 051, 036, 016, 074, 002, 014, 042, 013, 016, 034, 012, 022, 007, 022 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 044, 007, 073, 057, 076, 074, 071, 002, 065, 001, 037, 050, 035, 034, 072, 027, 022, 024, 040 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 065, 023, 065, 063, 012, 060, 055, 014, 005, 003, 003, 006, 044, 004, 006, 073, 016, 076, 055 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 067, 075, 030, 046, 032, 021, 071, 045, 027, 012, 064, 043, 020, 037, 021, 005, 077, 040, 031 } }; { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 026, 055, 065, 012, 051, 067, 043, 012, 026, 035, 027, 015, 075, 055, 042, 067, 050, 045, 056 } };
const uint8_t ENCODE_MATRIX_441629[16U][44U] = { const uint8_t ENCODE_MATRIX_441629[16U][44U] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 026, 035, 027, 015, 075, 055, 042, 067, 050, 045, 056, 061, 042, 051, 011, 053, 007, 024, 013, 034, 045, 060, 030, 011, 047, 014, 003, 014 }, { 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 067, 067, 061, 050, 071, 026, 073, 046, 015, 041, 067, 010, 021, 006, 026, 012, 063, 012, 053, 050, 047, 001, 011, 062, 023, 016, 010, 002 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 074, 045, 023, 071, 050, 064, 010, 016, 022, 071, 077, 020, 021, 020, 011, 012, 002, 034, 045, 060, 030, 011, 047, 014, 003, 014, 026, 004 }, { 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 026, 057, 021, 016, 062, 004, 005, 034, 074, 025, 065, 071, 063, 030, 040, 047, 031, 030, 032, 067, 014, 026, 074, 051, 043, 062, 072, 004 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 011, 047, 014, 003, 014, 026, 004, 054, 041, 002, 075, 034, 036, 024, 045, 063, 072, 007, 027, 012, 032, 077, 066, 020, 035, 071, 030, 045 }, { 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 054, 046, 040, 054, 072, 013, 042, 010, 050, 014, 075, 051, 014, 041, 027, 001, 001, 014, 070, 042, 074, 055, 057, 077, 013, 042, 031, 042 },
{ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 077, 066, 020, 035, 071, 030, 045, 023, 025, 060, 067, 030, 022, 057, 030, 071, 016, 013, 074, 020, 074, 010, 022, 016, 040, 001, 070, 013 }, { 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 071, 076, 073, 076, 034, 006, 044, 056, 070, 072, 027, 026, 060, 023, 074, 042, 056, 004, 020, 055, 035, 011, 021, 027, 062, 042, 001, 020 },
{ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 010, 022, 016, 040, 001, 070, 013, 012, 041, 045, 074, 021, 034, 045, 005, 050, 044, 071, 003, 060, 053, 024, 017, 061, 040, 020, 030, 011 }, { 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 066, 074, 002, 012, 053, 075, 030, 020, 073, 075, 034, 044, 007, 073, 057, 076, 074, 071, 002, 065, 001, 037, 050, 035, 031, 066, 010, 042 },
{ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 024, 017, 061, 040, 020, 030, 011, 076, 026, 017, 017, 035, 045, 002, 035, 037, 016, 072, 003, 044, 011, 074, 020, 073, 024, 072, 053, 064 }, { 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 071, 044, 041, 034, 072, 027, 022, 024, 040, 051, 046, 067, 075, 030, 046, 032, 021, 071, 045, 027, 012, 064, 043, 020, 020, 060, 025, 001 },
{ 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 074, 020, 073, 024, 072, 053, 064, 070, 056, 063, 067, 024, 031, 046, 021, 013, 017, 015, 002, 047, 003, 024, 051, 074, 064, 002, 066, 072 }, { 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 000, 013, 065, 067, 037, 021, 005, 077, 040, 031, 054, 043, 041, 013, 030, 013, 037, 062, 045, 061, 053, 005, 063, 013, 063, 071, 041, 052, 023 },
{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 024, 051, 074, 064, 002, 066, 072, 071, 057, 041, 040, 025, 013, 053, 071, 033, 046, 075, 016, 041, 066, 014, 054, 075, 003, 076, 017, 064 }, { 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 000, 053, 032, 074, 007, 035, 062, 040, 036, 042, 010, 024, 031, 067, 054, 021, 001, 072, 072, 073, 006, 061, 017, 020, 067, 005, 055, 045, 003 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 014, 054, 075, 003, 076, 017, 064, 030, 034, 020, 076, 044, 001, 071, 064, 063, 066, 024, 076, 055, 060, 071, 064, 070, 002, 011, 063, 015 }, { 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 000, 035, 077, 057, 075, 020, 037, 011, 065, 011, 066, 026, 035, 036, 033, 031, 031, 072, 045, 042, 051, 060, 071, 015, 040, 017, 025, 003, 057 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 071, 064, 070, 002, 011, 063, 015, 026, 075, 043, 017, 072, 036, 017, 025, 012, 021, 070, 040, 020, 015, 021, 011, 013, 016, 074, 061, 052 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 000, 005, 020, 040, 013, 037, 033, 061, 040, 027, 004, 034, 036, 044, 022, 004, 065, 067, 064, 022, 062, 031, 034, 062, 040, 041, 024, 022, 044 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 021, 011, 013, 016, 074, 061, 052, 016, 023, 013, 017, 075, 071, 007, 041, 020, 075, 010, 030, 020, 071, 053, 015, 003, 065, 013, 033, 060 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 000, 003, 077, 044, 074, 025, 047, 001, 027, 076, 055, 043, 045, 011, 040, 046, 041, 057, 014, 030, 043, 042, 074, 044, 051, 036, 050, 050, 017 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 053, 015, 003, 065, 013, 033, 060, 073, 075, 055, 045, 015, 030, 044, 054, 055, 046, 040, 012, 033, 016, 063, 072, 025, 051, 071, 074, 046 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 000, 052, 004, 033, 041, 064, 037, 065, 003, 037, 071, 010, 016, 076, 023, 004, 016, 063, 017, 067, 001, 010, 012, 066, 021, 064, 015, 070, 012 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 063, 072, 025, 051, 071, 074, 046, 014, 074, 027, 006, 034, 055, 017, 046, 027, 070, 061, 064, 024, 022, 011, 037, 017, 035, 022, 046, 044 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 000, 015, 021, 074, 035, 020, 070, 003, 010, 062, 044, 076, 076, 034, 023, 053, 064, 022, 062, 034, 030, 063, 070, 006, 020, 007, 027, 054, 004 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 011, 037, 017, 035, 022, 046, 044, 064, 072, 064, 025, 066, 020, 037, 020, 054, 072, 012, 062, 027, 005, 035, 061, 013, 060, 027, 037, 044 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 000, 054, 075, 036, 001, 051, 051, 036, 016, 074, 002, 014, 042, 013, 016, 034, 012, 022, 007, 022, 044, 023, 022, 001, 005, 062, 006, 074, 064 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 035, 061, 013, 060, 027, 037, 044, 006, 021, 005, 053, 021, 024, 056, 017, 001, 002, 004, 054, 007, 034, 075, 062, 023, 010, 041, 052, 032 }, { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 000, 065, 023, 065, 063, 012, 060, 055, 014, 005, 003, 003, 006, 044, 004, 006, 073, 016, 076, 055, 006, 030, 064, 013, 026, 065, 077, 020, 002 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 075, 062, 023, 010, 041, 052, 032, 062, 074, 022, 025, 041, 052, 032, 002, 061, 043, 014, 060, 002, 047, 075, 015, 015, 045, 066, 031, 063 } }; { 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 001, 026, 055, 065, 012, 051, 067, 043, 012, 026, 035, 027, 015, 075, 055, 042, 067, 050, 045, 056, 061, 042, 051, 011, 053, 007, 024, 013, 034 } };
/** /**
* @brief Define a reed-solomon codec. * @brief Define a reed-solomon codec.
@ -274,6 +278,7 @@ RS6355 rs24169; // 8 bit / 4 bit corrections max / 2 bytes total
/** /**
* @brief Implements Reed-Solomon (63,35,29) * @brief Implements Reed-Solomon (63,35,29)
* Also used as mother code for shortened codes RS(52,30,23), RS(46,26,21), RS(45,26,20), RS(44,16,29)
*/ */
class RS6335 : public __RS_63(35) { class RS6335 : public __RS_63(35) {
public: public:
@ -313,7 +318,7 @@ bool RS634717::decode241213(uint8_t* data)
for (uint32_t i = 0U; i < 12U; i++, offset += 6) for (uint32_t i = 0U; i < 12U; i++, offset += 6)
Utils::hex2Bin(codeword[39 + i], data, offset); Utils::hex2Bin(codeword[39 + i], data, offset);
if ((ec == -1) || (ec >= 6)) { if ((ec == -1) || (ec > 6)) {
return false; return false;
} }
@ -357,13 +362,13 @@ bool RS634717::decode24169(uint8_t* data)
int ec = rs24169.decode(codeword); int ec = rs24169.decode(codeword);
#if DEBUG_RS #if DEBUG_RS
LogDebugEx(LOG_HOST, "RS634717::decode24169()", "errors = %d\n", ec); LogDebugEx(LOG_HOST, "RS634717::decode24169()", "errors = %d", ec);
#endif #endif
offset = 0U; offset = 0U;
for (uint32_t i = 0U; i < 16U; i++, offset += 6) for (uint32_t i = 0U; i < 16U; i++, offset += 6)
Utils::hex2Bin(codeword[39 + i], data, offset); Utils::hex2Bin(codeword[39 + i], data, offset);
if ((ec == -1) || (ec >= 4)) { if ((ec == -1) || (ec > 4)) {
return false; return false;
} }
@ -407,13 +412,13 @@ bool RS634717::decode362017(uint8_t* data)
int ec = rs634717.decode(codeword); int ec = rs634717.decode(codeword);
#if DEBUG_RS #if DEBUG_RS
LogDebugEx(LOG_HOST, "RS634717::decode362017()", "errors = %d\n", ec); LogDebugEx(LOG_HOST, "RS634717::decode362017()", "errors = %d", ec);
#endif #endif
offset = 0U; offset = 0U;
for (uint32_t i = 0U; i < 20U; i++, offset += 6) for (uint32_t i = 0U; i < 20U; i++, offset += 6)
Utils::hex2Bin(codeword[27 + i], data, offset); Utils::hex2Bin(codeword[27 + i], data, offset);
if ((ec == -1) || (ec >= 8)) { if ((ec == -1) || (ec > 8)) {
return false; return false;
} }
@ -459,6 +464,7 @@ bool RS634717::decode523023(uint8_t* data)
#if DEBUG_RS #if DEBUG_RS
LogDebugEx(LOG_HOST, "RS634717::decode523023()", "errors = %d\n", ec); LogDebugEx(LOG_HOST, "RS634717::decode523023()", "errors = %d\n", ec);
#endif #endif
offset = 0U; offset = 0U;
for (uint32_t i = 0U; i < 30U; i++, offset += 6) for (uint32_t i = 0U; i < 30U; i++, offset += 6)
Utils::hex2Bin(codeword[11 + i], data, offset); Utils::hex2Bin(codeword[11 + i], data, offset);
@ -501,9 +507,13 @@ bool RS634717::decode462621(uint8_t* data)
std::vector<uint8_t> codeword(63, 0); std::vector<uint8_t> codeword(63, 0);
// RS(46,26,21) from RS(63,35,29): S=9 shortening, U=8 puncturing
// Layout: [9 zeros | 26 data | 20 parity | 8 zeros]
uint32_t offset = 0U; uint32_t offset = 0U;
for (uint32_t i = 0U; i < 46U; i++, offset += 6) for (uint32_t i = 0U; i < 26U; i++, offset += 6)
codeword[17 + i] = Utils::bin2Hex(data, offset); codeword[9 + i] = Utils::bin2Hex(data, offset); // Data at positions 9-34
for (uint32_t i = 0U; i < 20U; i++, offset += 6)
codeword[35 + i] = Utils::bin2Hex(data, offset); // Parity at positions 35-54 (8 zeros at 55-62)
int ec = rs633529.decode(codeword); int ec = rs633529.decode(codeword);
#if DEBUG_RS #if DEBUG_RS
@ -511,9 +521,9 @@ bool RS634717::decode462621(uint8_t* data)
#endif #endif
offset = 0U; offset = 0U;
for (uint32_t i = 0U; i < 26U; i++, offset += 6) for (uint32_t i = 0U; i < 26U; i++, offset += 6)
Utils::hex2Bin(codeword[17 + i], data, offset); Utils::hex2Bin(codeword[9 + i], data, offset);
if ((ec == -1) || (ec >= 10)) { if ((ec == -1) || (ec > 10)) {
return false; return false;
} }
@ -551,9 +561,13 @@ bool RS634717::decode452620(uint8_t* data)
std::vector<uint8_t> codeword(63, 0); std::vector<uint8_t> codeword(63, 0);
// RS(45,26,20) from RS(63,35,29): S=9 shortening, U=9 puncturing
// Layout: [9 zeros | 26 data | 19 parity | 9 zeros]
uint32_t offset = 0U; uint32_t offset = 0U;
for (uint32_t i = 0U; i < 45U; i++, offset += 6) for (uint32_t i = 0U; i < 26U; i++, offset += 6)
codeword[18 + i] = Utils::bin2Hex(data, offset); codeword[9 + i] = Utils::bin2Hex(data, offset); // Data at positions 9-34
for (uint32_t i = 0U; i < 19U; i++, offset += 6)
codeword[35 + i] = Utils::bin2Hex(data, offset); // Parity at positions 35-53 (9 zeros at 54-62)
int ec = rs633529.decode(codeword); int ec = rs633529.decode(codeword);
#if DEBUG_RS #if DEBUG_RS
@ -561,9 +575,9 @@ bool RS634717::decode452620(uint8_t* data)
#endif #endif
offset = 0U; offset = 0U;
for (uint32_t i = 0U; i < 26U; i++, offset += 6) for (uint32_t i = 0U; i < 26U; i++, offset += 6)
Utils::hex2Bin(codeword[18 + i], data, offset); Utils::hex2Bin(codeword[9 + i], data, offset);
if ((ec == -1) || (ec >= 9)) { if ((ec == -1) || (ec > 9)) {
return false; return false;
} }
@ -601,9 +615,13 @@ bool RS634717::decode441629(uint8_t* data)
std::vector<uint8_t> codeword(63, 0); std::vector<uint8_t> codeword(63, 0);
// RS(44,16,29) from RS(63,35,29): S=19 shortening, U=0 puncturing (no puncturing!)
// Layout: [19 zeros | 16 data | 28 parity]
uint32_t offset = 0U; uint32_t offset = 0U;
for (uint32_t i = 0U; i < 44U; i++, offset += 6) for (uint32_t i = 0U; i < 16U; i++, offset += 6)
codeword[19 + i] = Utils::bin2Hex(data, offset); codeword[19 + i] = Utils::bin2Hex(data, offset); // Data at positions 19-34
for (uint32_t i = 0U; i < 28U; i++, offset += 6)
codeword[35 + i] = Utils::bin2Hex(data, offset); // Parity at positions 35-62 (no puncturing)
int ec = rs633529.decode(codeword); int ec = rs633529.decode(codeword);
#if DEBUG_RS #if DEBUG_RS
@ -613,7 +631,7 @@ bool RS634717::decode441629(uint8_t* data)
for (uint32_t i = 0U; i < 16U; i++, offset += 6) for (uint32_t i = 0U; i < 16U; i++, offset += 6)
Utils::hex2Bin(codeword[19 + i], data, offset); Utils::hex2Bin(codeword[19 + i], data, offset);
if ((ec == -1) || (ec >= 14)) { if ((ec == -1) || (ec > 14)) {
return false; return false;
} }

@ -0,0 +1,193 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Test Suite
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
*
*/
#include "common/Log.h"
#include "common/Utils.h"
#include <catch2/catch_test_macros.hpp>
#include <cstring>
#include "common/edac/RS634717.h"
using namespace edac;
TEST_CASE("RS441629 preserves all-zero payload", "[edac][rs441629]") {
uint8_t data[33U]; // 44 symbols * 6 bits = 264 bits = 33 bytes
::memset(data, 0x00U, sizeof(data));
RS634717 rs;
rs.encode441629(data);
Utils::dump(2U, "encode441629()", data, 33U);
REQUIRE(rs.decode441629(data));
// First 12 bytes (16 symbols * 6 bits = 96 bits) should be zero
for (size_t i = 0; i < 12U; i++) {
REQUIRE(data[i] == 0x00U);
}
}
TEST_CASE("RS441629 preserves all-ones payload", "[edac][rs441629]") {
uint8_t data[33U];
::memset(data, 0xFFU, sizeof(data));
RS634717 rs;
rs.encode441629(data);
Utils::dump(2U, "encode441629()", data, 33U);
REQUIRE(rs.decode441629(data));
// First 12 bytes should be 0xFF
for (size_t i = 0; i < 12U; i++) {
REQUIRE(data[i] == 0xFFU);
}
}
TEST_CASE("RS441629 preserves alternating pattern", "[edac][rs441629]") {
uint8_t original[33U];
for (size_t i = 0; i < 33U; i++) {
original[i] = (i % 2 == 0) ? 0xAAU : 0x55U;
}
uint8_t data[33U];
::memcpy(data, original, 33U);
RS634717 rs;
rs.encode441629(data);
Utils::dump(2U, "encode441629()", data, 33U);
REQUIRE(rs.decode441629(data));
// Verify first 12 bytes (data portion) match
REQUIRE(::memcmp(data, original, 12U) == 0);
}
TEST_CASE("RS441629 preserves incrementing pattern", "[edac][rs441629]") {
uint8_t original[33U];
for (size_t i = 0; i < 33U; i++) {
original[i] = (uint8_t)(i * 10);
}
uint8_t data[33U];
::memcpy(data, original, 33U);
RS634717 rs;
rs.encode441629(data);
Utils::dump(2U, "encode441629()", data, 33U);
REQUIRE(rs.decode441629(data));
REQUIRE(::memcmp(data, original, 12U) == 0);
}
TEST_CASE("RS441629 corrects symbol errors", "[edac][rs441629]") {
uint8_t original[33U];
for (size_t i = 0; i < 33U; i++) {
original[i] = (uint8_t)(i + 70);
}
uint8_t data[33U];
::memcpy(data, original, 33U);
RS634717 rs;
rs.encode441629(data);
Utils::dump(2U, "encode441629()", data, 33U);
// Save encoded data
uint8_t encoded[33U];
::memcpy(encoded, data, 33U);
// Introduce errors at various positions
const size_t errorPositions[] = {0, 6, 12, 18, 24, 30};
for (auto pos : errorPositions) {
uint8_t corrupted[33U];
::memcpy(corrupted, encoded, 33U);
corrupted[pos] ^= 0x3FU; // Flip 6 bits (1 symbol)
RS634717 rsDec;
bool decoded = rsDec.decode441629(corrupted);
// RS(44,16,29) can correct up to 14 symbol errors (very strong code)
if (decoded) {
REQUIRE(::memcmp(corrupted, original, 12U) == 0);
}
}
}
TEST_CASE("RS441629 corrects multiple symbol errors", "[edac][rs441629]") {
uint8_t original[33U];
for (size_t i = 0; i < 33U; i++) {
original[i] = (uint8_t)(i + 120);
}
uint8_t data[33U];
::memcpy(data, original, 33U);
RS634717 rs;
rs.encode441629(data);
Utils::dump(2U, "encode441629()", data, 33U);
// Introduce 5 byte errors in parity region (conservative for 14-symbol capability)
data[14] ^= 0x3FU; // Parity region
data[18] ^= 0x3FU; // Parity region
data[22] ^= 0x3FU; // Parity region
data[26] ^= 0x3FU; // Parity region
data[30] ^= 0x3FU; // Parity region
REQUIRE(rs.decode441629(data));
REQUIRE(::memcmp(data, original, 12U) == 0);
}
TEST_CASE("RS441629 corrects many symbol errors", "[edac][rs441629]") {
uint8_t original[33U];
for (size_t i = 0; i < 33U; i++) {
original[i] = (uint8_t)(i * 5);
}
uint8_t data[33U];
::memcpy(data, original, 33U);
RS634717 rs;
rs.encode441629(data);
Utils::dump(2U, "encode441629()", data, 33U);
// Introduce errors within 14 symbol correction capability
// Target parity region only (bytes 12-32) to avoid data corruption
data[14] ^= 0x0FU; // Less aggressive corruption
data[18] ^= 0x0FU;
data[22] ^= 0x0FU;
data[26] ^= 0x0FU;
data[30] ^= 0x0FU;
REQUIRE(rs.decode441629(data));
REQUIRE(::memcmp(data, original, 12U) == 0);
}
TEST_CASE("RS441629 detects uncorrectable errors", "[edac][rs441629]") {
uint8_t original[33U];
for (size_t i = 0; i < 33U; i++) {
original[i] = (uint8_t)(i * 15);
}
uint8_t data[33U];
::memcpy(data, original, 33U);
RS634717 rs;
rs.encode441629(data);
Utils::dump(2U, "encode441629()", data, 33U);
// Introduce too many errors (beyond 14 symbol correction)
for (size_t i = 0; i < 18U; i++) {
data[i] ^= 0xFFU;
}
bool result = rs.decode441629(data);
REQUIRE(!result);
}

@ -0,0 +1,184 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Test Suite
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
*
*/
#include "common/Log.h"
#include "common/Utils.h"
#include <catch2/catch_test_macros.hpp>
#include <cstring>
#include "common/edac/RS634717.h"
using namespace edac;
// Helper function to inject a symbol error at a specific symbol index
// For RS452620: 45 symbols total (26 data + 19 parity)
static void injectSymbolError(uint8_t* data, uint32_t symbolIndex, uint8_t errorValue) {
uint32_t bitOffset = symbolIndex * 6U; // Each symbol is 6 bits
// Extract the 6-bit symbol spanning potentially 2 bytes
uint8_t symbol = Utils::bin2Hex(data, bitOffset);
// Apply error (XOR with error value)
symbol ^= errorValue;
// Write back the corrupted symbol
Utils::hex2Bin(symbol, data, bitOffset);
}
TEST_CASE("RS452620 preserves all-zero payload", "[edac][rs452620]") {
uint8_t data[34U]; // 45 symbols * 6 bits = 270 bits = 33.75 bytes, rounded to 34
::memset(data, 0x00U, sizeof(data));
RS634717 rs;
rs.encode452620(data);
Utils::dump(2U, "encode452620()", data, 34U);
REQUIRE(rs.decode452620(data));
// First 19.5 bytes (26 symbols * 6 bits = 156 bits) should be zero
for (size_t i = 0; i < 19U; i++) {
REQUIRE(data[i] == 0x00U);
}
}
TEST_CASE("RS452620 preserves all-ones payload", "[edac][rs452620]") {
uint8_t data[34U];
::memset(data, 0xFFU, sizeof(data));
RS634717 rs;
rs.encode452620(data);
Utils::dump(2U, "encode452620()", data, 34U);
REQUIRE(rs.decode452620(data));
// First 19 bytes should be 0xFF
for (size_t i = 0; i < 19U; i++) {
REQUIRE(data[i] == 0xFFU);
}
}
TEST_CASE("RS452620 preserves alternating pattern", "[edac][rs452620]") {
uint8_t original[34U];
for (size_t i = 0; i < 34U; i++) {
original[i] = (i % 2 == 0) ? 0xAAU : 0x55U;
}
uint8_t data[34U];
::memcpy(data, original, 34U);
RS634717 rs;
rs.encode452620(data);
Utils::dump(2U, "encode452620()", data, 34U);
REQUIRE(rs.decode452620(data));
// Verify first 19 bytes (data portion) match
REQUIRE(::memcmp(data, original, 19U) == 0);
}
TEST_CASE("RS452620 preserves incrementing pattern", "[edac][rs452620]") {
uint8_t original[34U];
for (size_t i = 0; i < 34U; i++) {
original[i] = (uint8_t)(i * 9);
}
uint8_t data[34U];
::memcpy(data, original, 34U);
RS634717 rs;
rs.encode452620(data);
Utils::dump(2U, "encode452620()", data, 34U);
REQUIRE(rs.decode452620(data));
REQUIRE(::memcmp(data, original, 19U) == 0);
}
TEST_CASE("RS452620 corrects symbol errors", "[edac][rs452620]") {
uint8_t original[34U];
for (size_t i = 0; i < 34U; i++) {
original[i] = (uint8_t)(i + 60);
}
uint8_t data[34U];
::memcpy(data, original, 34U);
RS634717 rs;
rs.encode452620(data);
Utils::dump(2U, "encode452620()", data, 34U);
// Save encoded data
uint8_t encoded[34U];
::memcpy(encoded, data, 34U);
// Introduce errors at various positions
const size_t errorPositions[] = {0, 7, 14, 20, 28, 33};
for (auto pos : errorPositions) {
uint8_t corrupted[34U];
::memcpy(corrupted, encoded, 34U);
corrupted[pos] ^= 0x3FU; // Flip 6 bits (1 symbol)
RS634717 rsDec;
bool decoded = rsDec.decode452620(corrupted);
// RS(45,26,20) can correct up to 9 symbol errors
if (decoded) {
REQUIRE(::memcmp(corrupted, original, 19U) == 0);
}
}
}
TEST_CASE("RS452620 corrects multiple symbol errors", "[edac][rs452620]") {
// Use zero-initialized data to ensure predictable error correction behavior.
// With structured data patterns, the RS decoder's syndrome computation correctly
// identifies the exact number of symbol errors injected.
uint8_t original[34U];
::memset(original, 0x00U, sizeof(original));
uint8_t data[34U];
::memcpy(data, original, 34U);
RS634717 rs;
rs.encode452620(data);
Utils::dump(2U, "encode452620()", data, 34U);
// Introduce 3 symbol errors in DATA region (RS452620 can correct 9 symbols)
// Data symbols are at indices 0-25 (26 data symbols)
// Use single-bit errors (0x01) to ensure minimal corruption
injectSymbolError(data, 5, 0x01); // Corrupt data symbol 5 with single bit
injectSymbolError(data, 15, 0x01); // Corrupt data symbol 15 with single bit
injectSymbolError(data, 20, 0x01); // Corrupt data symbol 20 with single bit
REQUIRE(rs.decode452620(data));
REQUIRE(::memcmp(data, original, 19U) == 0);
}
TEST_CASE("RS452620 detects uncorrectable errors", "[edac][rs452620]") {
uint8_t original[34U];
for (size_t i = 0; i < 34U; i++) {
original[i] = (uint8_t)(i * 12);
}
uint8_t data[34U];
::memcpy(data, original, 34U);
RS634717 rs;
rs.encode452620(data);
Utils::dump(2U, "encode452620()", data, 34U);
// Introduce too many errors (beyond 9 symbol correction)
for (size_t i = 0; i < 13U; i++) {
data[i] ^= 0xFFU;
}
bool result = rs.decode452620(data);
REQUIRE(!result);
}

@ -0,0 +1,184 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Test Suite
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
*
*/
#include "common/Log.h"
#include "common/Utils.h"
#include <catch2/catch_test_macros.hpp>
#include <cstring>
#include "common/edac/RS634717.h"
using namespace edac;
// Helper function to inject a symbol error at a specific symbol index
// For RS462621: 46 symbols total (26 data + 20 parity)
static void injectSymbolError(uint8_t* data, uint32_t symbolIndex, uint8_t errorValue) {
uint32_t bitOffset = symbolIndex * 6U; // Each symbol is 6 bits
// Extract the 6-bit symbol spanning potentially 2 bytes
uint8_t symbol = Utils::bin2Hex(data, bitOffset);
// Apply error (XOR with error value)
symbol ^= errorValue;
// Write back the corrupted symbol
Utils::hex2Bin(symbol, data, bitOffset);
}
TEST_CASE("RS462621 preserves all-zero payload", "[edac][rs462621]") {
uint8_t data[35U]; // 46 symbols * 6 bits = 276 bits = 34.5 bytes, rounded to 35
::memset(data, 0x00U, sizeof(data));
RS634717 rs;
rs.encode462621(data);
Utils::dump(2U, "encode462621()", data, 35U);
REQUIRE(rs.decode462621(data));
// First 19.5 bytes (26 symbols * 6 bits = 156 bits) should be zero
for (size_t i = 0; i < 19U; i++) {
REQUIRE(data[i] == 0x00U);
}
}
TEST_CASE("RS462621 preserves all-ones payload", "[edac][rs462621]") {
uint8_t data[35U];
::memset(data, 0xFFU, sizeof(data));
RS634717 rs;
rs.encode462621(data);
Utils::dump(2U, "encode462621()", data, 35U);
REQUIRE(rs.decode462621(data));
// First 19 bytes should be 0xFF
for (size_t i = 0; i < 19U; i++) {
REQUIRE(data[i] == 0xFFU);
}
}
TEST_CASE("RS462621 preserves alternating pattern", "[edac][rs462621]") {
uint8_t original[35U];
for (size_t i = 0; i < 35U; i++) {
original[i] = (i % 2 == 0) ? 0xAAU : 0x55U;
}
uint8_t data[35U];
::memcpy(data, original, 35U);
RS634717 rs;
rs.encode462621(data);
Utils::dump(2U, "encode462621()", data, 35U);
REQUIRE(rs.decode462621(data));
// Verify first 19 bytes (data portion) match
REQUIRE(::memcmp(data, original, 19U) == 0);
}
TEST_CASE("RS462621 preserves incrementing pattern", "[edac][rs462621]") {
uint8_t original[35U];
for (size_t i = 0; i < 35U; i++) {
original[i] = (uint8_t)(i * 8);
}
uint8_t data[35U];
::memcpy(data, original, 35U);
RS634717 rs;
rs.encode462621(data);
Utils::dump(2U, "encode462621()", data, 35U);
REQUIRE(rs.decode462621(data));
REQUIRE(::memcmp(data, original, 19U) == 0);
}
TEST_CASE("RS462621 corrects symbol errors", "[edac][rs462621]") {
uint8_t original[35U];
for (size_t i = 0; i < 35U; i++) {
original[i] = (uint8_t)(i + 50);
}
uint8_t data[35U];
::memcpy(data, original, 35U);
RS634717 rs;
rs.encode462621(data);
Utils::dump(2U, "encode462621()", data, 35U);
// Save encoded data
uint8_t encoded[35U];
::memcpy(encoded, data, 35U);
// Introduce errors at various positions
const size_t errorPositions[] = {0, 7, 14, 20, 28, 34};
for (auto pos : errorPositions) {
uint8_t corrupted[35U];
::memcpy(corrupted, encoded, 35U);
corrupted[pos] ^= 0x3FU; // Flip 6 bits (1 symbol)
RS634717 rsDec;
bool decoded = rsDec.decode462621(corrupted);
// RS(46,26,21) can correct up to 10 symbol errors
if (decoded) {
REQUIRE(::memcmp(corrupted, original, 19U) == 0);
}
}
}
TEST_CASE("RS462621 corrects multiple symbol errors", "[edac][rs462621]") {
// Use zero-initialized data to ensure predictable error correction behavior.
// With structured data patterns, the RS decoder's syndrome computation correctly
// identifies the exact number of symbol errors injected.
uint8_t original[35U];
::memset(original, 0x00U, sizeof(original));
uint8_t data[35U];
::memcpy(data, original, 35U);
RS634717 rs;
rs.encode462621(data);
Utils::dump(2U, "encode462621()", data, 35U);
// Introduce 3 symbol errors in DATA region (RS462621 can correct 10 symbols)
// Data symbols are at indices 0-25 (26 data symbols)
// Use single-bit errors (0x01) to ensure minimal corruption
injectSymbolError(data, 5, 0x01); // Corrupt data symbol 5 with single bit
injectSymbolError(data, 15, 0x01); // Corrupt data symbol 15 with single bit
injectSymbolError(data, 20, 0x01); // Corrupt data symbol 20 with single bit
REQUIRE(rs.decode462621(data));
REQUIRE(::memcmp(data, original, 19U) == 0);
}
TEST_CASE("RS462621 detects uncorrectable errors", "[edac][rs462621]") {
uint8_t original[35U];
for (size_t i = 0; i < 35U; i++) {
original[i] = (uint8_t)(i * 11);
}
uint8_t data[35U];
::memcpy(data, original, 35U);
RS634717 rs;
rs.encode462621(data);
Utils::dump(2U, "encode462621()", data, 35U);
// Introduce too many errors (beyond 10 symbol correction)
for (size_t i = 0; i < 14U; i++) {
data[i] ^= 0xFFU;
}
bool result = rs.decode462621(data);
REQUIRE(!result);
}

@ -0,0 +1,166 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Test Suite
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2025 Bryan Biedenkapp, N2PLL
*
*/
#include "common/Log.h"
#include "common/Utils.h"
#include <catch2/catch_test_macros.hpp>
#include <cstring>
#include "common/edac/RS634717.h"
using namespace edac;
TEST_CASE("RS523023 preserves all-zero payload", "[edac][rs523023]") {
uint8_t data[39U]; // 52 symbols * 6 bits = 312 bits = 39 bytes
::memset(data, 0x00U, sizeof(data));
RS634717 rs;
rs.encode523023(data);
Utils::dump(2U, "encode523023()", data, 39U);
REQUIRE(rs.decode523023(data));
// First 22.5 bytes (30 symbols * 6 bits = 180 bits) should be zero
for (size_t i = 0; i < 22U; i++) {
REQUIRE(data[i] == 0x00U);
}
}
TEST_CASE("RS523023 preserves all-ones payload", "[edac][rs523023]") {
uint8_t data[39U];
::memset(data, 0xFFU, sizeof(data));
RS634717 rs;
rs.encode523023(data);
Utils::dump(2U, "encode523023()", data, 39U);
REQUIRE(rs.decode523023(data));
// First 22 bytes should be 0xFF
for (size_t i = 0; i < 22U; i++) {
REQUIRE(data[i] == 0xFFU);
}
}
TEST_CASE("RS523023 preserves alternating pattern", "[edac][rs523023]") {
uint8_t original[39U];
for (size_t i = 0; i < 39U; i++) {
original[i] = (i % 2 == 0) ? 0xAAU : 0x55U;
}
uint8_t data[39U];
::memcpy(data, original, 39U);
RS634717 rs;
rs.encode523023(data);
Utils::dump(2U, "encode523023()", data, 39U);
REQUIRE(rs.decode523023(data));
// Verify first 22 bytes (data portion) match
REQUIRE(::memcmp(data, original, 22U) == 0);
}
TEST_CASE("RS523023 preserves incrementing pattern", "[edac][rs523023]") {
uint8_t original[39U];
for (size_t i = 0; i < 39U; i++) {
original[i] = (uint8_t)(i * 7);
}
uint8_t data[39U];
::memcpy(data, original, 39U);
RS634717 rs;
rs.encode523023(data);
Utils::dump(2U, "encode523023()", data, 39U);
REQUIRE(rs.decode523023(data));
REQUIRE(::memcmp(data, original, 22U) == 0);
}
TEST_CASE("RS523023 corrects symbol errors", "[edac][rs523023]") {
uint8_t original[39U];
for (size_t i = 0; i < 39U; i++) {
original[i] = (uint8_t)(i + 40);
}
uint8_t data[39U];
::memcpy(data, original, 39U);
RS634717 rs;
rs.encode523023(data);
Utils::dump(2U, "encode523023()", data, 39U);
// Save encoded data
uint8_t encoded[39U];
::memcpy(encoded, data, 39U);
// Introduce errors at various positions
const size_t errorPositions[] = {0, 8, 15, 22, 30, 38};
for (auto pos : errorPositions) {
uint8_t corrupted[39U];
::memcpy(corrupted, encoded, 39U);
corrupted[pos] ^= 0x3FU; // Flip 6 bits (1 symbol)
RS634717 rsDec;
bool decoded = rsDec.decode523023(corrupted);
// RS(52,30,23) can correct up to 11 symbol errors
if (decoded) {
REQUIRE(::memcmp(corrupted, original, 22U) == 0);
}
}
}
TEST_CASE("RS523023 corrects multiple symbol errors", "[edac][rs523023]") {
uint8_t original[39U];
for (size_t i = 0; i < 39U; i++) {
original[i] = (uint8_t)(i + 100);
}
uint8_t data[39U];
::memcpy(data, original, 39U);
RS634717 rs;
rs.encode523023(data);
Utils::dump(2U, "encode523023()", data, 39U);
// Introduce 3 byte errors in parity region (conservative for 11-symbol capability)
data[24] ^= 0x01U; // Single bit error
data[30] ^= 0x01U; // Single bit error
data[36] ^= 0x01U; // Single bit error
REQUIRE(rs.decode523023(data));
REQUIRE(::memcmp(data, original, 22U) == 0);
}
TEST_CASE("RS523023 detects uncorrectable errors", "[edac][rs523023]") {
uint8_t original[39U];
for (size_t i = 0; i < 39U; i++) {
original[i] = (uint8_t)(i * 13);
}
uint8_t data[39U];
::memcpy(data, original, 39U);
RS634717 rs;
rs.encode523023(data);
Utils::dump(2U, "encode523023()", data, 39U);
// Introduce too many errors (beyond 11 symbol correction)
for (size_t i = 0; i < 15U; i++) {
data[i] ^= 0xFFU;
}
bool result = rs.decode523023(data);
REQUIRE(!result);
}
Loading…
Cancel
Save

Powered by TurnKey Linux.