pub const MAX_PARITY_ERRORS: usize = 3;
#[rustfmt::skip]
pub static SYNDROM: [u16; 1936] = [
0x1189, 0x2312, 0x4624, 0x8c48, 0x1081, 0x2102, 0x4204, 0x8408,
0x19d8, 0x33b0, 0x6760, 0xcec0, 0x9591, 0x2333, 0x4666, 0x8ccc,
0x5adc, 0xb5b8, 0x6361, 0xc6c2, 0x8595, 0x33b, 0x676, 0xcec,
0x1cbb, 0x3976, 0x72ec, 0xe5d8, 0xc3a1, 0x8f53, 0x16b7, 0x2d6e,
0xb44, 0x1688, 0x2d10, 0x5a20, 0xb440, 0x6091, 0xc122, 0x8a55,
0x42b, 0x856, 0x10ac, 0x2158, 0x42b0, 0x8560, 0x2d1, 0x5a2,
0x9fd5, 0x37bb, 0x6f76, 0xdeec, 0xb5c9, 0x6383, 0xc706, 0x861d,
0x81bf, 0xb6f, 0x16de, 0x2dbc, 0x5b78, 0xb6f0, 0x65f1, 0xcbe2,
0x4dfd, 0x9bfa, 0x3fe5, 0x7fca, 0xff94, 0xf739, 0xe663, 0xc4d7,
0x2c27, 0x584e, 0xb09c, 0x6929, 0xd252, 0xacb5, 0x517b, 0xa2f6,
0x5591, 0xab22, 0x5e55, 0xbcaa, 0x7145, 0xe28a, 0xcd05, 0x921b,
0x8555, 0x2bb, 0x576, 0xaec, 0x15d8, 0x2bb0, 0x5760, 0xaec0,
0x5ad, 0xb5a, 0x16b4, 0x2d68, 0x5ad0, 0xb5a0, 0x6351, 0xc6a2,
0x7eea, 0xfdd4, 0xf3b9, 0xef63, 0xd6d7, 0xa5bf, 0x436f, 0x86de,
0x482a, 0x9054, 0x28b9, 0x5172, 0xa2e4, 0x4dd9, 0x9bb2, 0x3f75,
0x8e10, 0x1431, 0x2862, 0x50c4, 0xa188, 0x4b01, 0x9602, 0x2415,
0x100f, 0x201e, 0x403c, 0x8078, 0x8e1, 0x11c2, 0x2384, 0x4708,
0xf8e7, 0xf9df, 0xfbaf, 0xff4f, 0xf68f, 0xe50f, 0xc20f, 0x8c0f,
0x9349, 0x2e83, 0x5d06, 0xba0c, 0x7c09, 0xf812, 0xf835, 0xf87b,
0xdf56, 0xb6bd, 0x656b, 0xcad6, 0x9dbd, 0x336b, 0x66d6, 0xcdac,
0x376c, 0x6ed8, 0xddb0, 0xb371, 0x6ef3, 0xdde6, 0xb3dd, 0x6fab,
0xa95d, 0x5aab, 0xb556, 0x62bd, 0xc57a, 0x82e5, 0xddb, 0x1bb6,
0x89c9, 0x1b83, 0x3706, 0x6e0c, 0xdc18, 0xb021, 0x6853, 0xd0a6,
0x5b44, 0xb688, 0x6501, 0xca02, 0x9c15, 0x303b, 0x6076, 0xc0ec,
0x47b, 0x8f6, 0x11ec, 0x23d8, 0x47b0, 0x8f60, 0x16d1, 0x2da2,
0xcd50, 0x92b1, 0x2d73, 0x5ae6, 0xb5cc, 0x6389, 0xc712, 0x8635,
0x5248, 0xa490, 0x4131, 0x8262, 0xcd5, 0x19aa, 0x3354, 0x66a8,
0xce1e, 0x942d, 0x204b, 0x4096, 0x812c, 0xa49, 0x1492, 0x2924,
0xf931, 0xfa73, 0xfcf7, 0xf1ff, 0xebef, 0xdfcf, 0xb78f, 0x670f,
0x20f3, 0x41e6, 0x83cc, 0xf89, 0x1f12, 0x3e24, 0x7c48, 0xf890,
0xc534, 0x8279, 0xce3, 0x19c6, 0x338c, 0x6718, 0xce30, 0x9471,
0x7762, 0xeec4, 0xd599, 0xa323, 0x4e57, 0x9cae, 0x314d, 0x629a,
0x4063, 0x80c6, 0x99d, 0x133a, 0x2674, 0x4ce8, 0x99d0, 0x3bb1,
0x51dd, 0xa3ba, 0x4f65, 0x9eca, 0x3585, 0x6b0a, 0xd614, 0xa439,
0xd39, 0x1a72, 0x34e4, 0x69c8, 0xd390, 0xaf31, 0x5673, 0xace6,
0xac4f, 0x508f, 0xa11e, 0x4a2d, 0x945a, 0x20a5, 0x414a, 0x8294,
0xba5f, 0x7caf, 0xf95e, 0xfaad, 0xfd4b, 0xf287, 0xed1f, 0xd22f,
0xaac8, 0x5d81, 0xbb02, 0x7e15, 0xfc2a, 0xf045, 0xe89b, 0xd927,
0x4aee, 0x95dc, 0x23a9, 0x4752, 0x8ea4, 0x1559, 0x2ab2, 0x5564,
0xe3a, 0x1c74, 0x38e8, 0x71d0, 0xe3a0, 0xcf51, 0x96b3, 0x2577,
0x9ed7, 0x35bf, 0x6b7e, 0xd6fc, 0xa5e9, 0x43c3, 0x8786, 0x71d,
0xa2ac, 0x4d49, 0x9a92, 0x3d35, 0x7a6a, 0xf4d4, 0xe1b9, 0xcb63,
0x6fc4, 0xdf88, 0xb701, 0x6613, 0xcc26, 0x905d, 0x28ab, 0x5156,
0x8047, 0x89f, 0x113e, 0x227c, 0x44f8, 0x89f0, 0x1bf1, 0x37e2,
0x363b, 0x6c76, 0xd8ec, 0xb9c9, 0x7b83, 0xf706, 0xe61d, 0xc42b,
0x8f66, 0x16dd, 0x2dba, 0x5b74, 0xb6e8, 0x65c1, 0xcb82, 0x9f15,
0x6bf, 0xd7e, 0x1afc, 0x35f8, 0x6bf0, 0xd7e0, 0xa7d1, 0x47b3,
0x4d7a, 0x9af4, 0x3df9, 0x7bf2, 0xf7e4, 0xe7d9, 0xc7a3, 0x8757,
0xdc90, 0xb131, 0x6a73, 0xd4e6, 0xa1dd, 0x4bab, 0x9756, 0x26bd,
0x9455, 0x20bb, 0x4176, 0x82ec, 0xdc9, 0x1b92, 0x3724, 0x6e48,
0x5bc, 0xb78, 0x16f0, 0x2de0, 0x5bc0, 0xb780, 0x6711, 0xce22,
0x7fe2, 0xffc4, 0xf799, 0xe723, 0xc657, 0x84bf, 0x16f, 0x2de,
0xc463, 0x80d7, 0x9bf, 0x137e, 0x26fc, 0x4df8, 0x9bf0, 0x3ff1,
0x5159, 0xa2b2, 0x4d75, 0x9aea, 0x3dc5, 0x7b8a, 0xf714, 0xe639,
0xcf15, 0x963b, 0x2467, 0x48ce, 0x919c, 0x2b29, 0x5652, 0xaca4,
0x47e3, 0x8fc6, 0x179d, 0x2f3a, 0x5e74, 0xbce8, 0x71c1, 0xe382,
0xd5d2, 0xa3b5, 0x4f7b, 0x9ef6, 0x35fd, 0x6bfa, 0xd7f4, 0xa7f9,
0xf54a, 0xe285, 0xcd1b, 0x9227, 0x2c5f, 0x58be, 0xb17c, 0x6ae9,
0xedab, 0xd347, 0xae9f, 0x552f, 0xaa5e, 0x5cad, 0xb95a, 0x7aa5,
0x1b34, 0x3668, 0x6cd0, 0xd9a0, 0xbb51, 0x7eb3, 0xfd66, 0xf2dd,
0x77bc, 0xef78, 0xd6e1, 0xa5d3, 0x43b7, 0x876e, 0x6cd, 0xd9a,
0x7f90, 0xff20, 0xf651, 0xe4b3, 0xc177, 0x8aff, 0x1def, 0x3bde,
0x94f6, 0x21fd, 0x43fa, 0x87f4, 0x7f9, 0xff2, 0x1fe4, 0x3fc8,
0x922d, 0x2c4b, 0x5896, 0xb12c, 0x6a49, 0xd492, 0xa135, 0x4a7b,
0xfa75, 0xfcfb, 0xf1e7, 0xebdf, 0xdfaf, 0xb74f, 0x668f, 0xcd1e,
0x24d0, 0x49a0, 0x9340, 0x2e91, 0x5d22, 0xba44, 0x7c99, 0xf932,
0xd6a9, 0xa543, 0x4297, 0x852e, 0x24d, 0x49a, 0x934, 0x1268,
0x381d, 0x703a, 0xe074, 0xc8f9, 0x99e3, 0x3bd7, 0x77ae, 0xef5c,
0xcb5c, 0x9ea9, 0x3543, 0x6a86, 0xd50c, 0xa209, 0x4c03, 0x9806,
0x9822, 0x3855, 0x70aa, 0xe154, 0xcab9, 0x9d63, 0x32d7, 0x65ae,
0x288, 0x510, 0xa20, 0x1440, 0x2880, 0x5100, 0xa200, 0x4c11,
0x842, 0x1084, 0x2108, 0x4210, 0x8420, 0x51, 0xa2, 0x144,
0x611e, 0xc23c, 0x8c69, 0x10c3, 0x2186, 0x430c, 0x8618, 0x421,
0xf99e, 0xfb2d, 0xfe4b, 0xf487, 0xe11f, 0xca2f, 0x9c4f, 0x308f,
0x7d0e, 0xfa1c, 0xfc29, 0xf043, 0xe897, 0xd93f, 0xba6f, 0x7ccf,
0xe903, 0xda17, 0xbc3f, 0x706f, 0xe0de, 0xc9ad, 0x9b4b, 0x3e87,
0x3272, 0x64e4, 0xc9c8, 0x9b81, 0x3f13, 0x7e26, 0xfc4c, 0xf089,
0x50a7, 0xa14e, 0x4a8d, 0x951a, 0x2225, 0x444a, 0x8894, 0x1939,
0xd1e5, 0xabdb, 0x5fa7, 0xbf4e, 0x768d, 0xed1a, 0xd225, 0xac5b,
0xb072, 0x68f5, 0xd1ea, 0xabc5, 0x5f9b, 0xbf36, 0x767d, 0xecfa,
0x5025, 0xa04a, 0x4885, 0x910a, 0x2a05, 0x540a, 0xa814, 0x5839,
0x76ff, 0xedfe, 0xd3ed, 0xafcb, 0x5787, 0xaf0e, 0x560d, 0xac1a,
0xf0e, 0x1e1c, 0x3c38, 0x7870, 0xf0e0, 0xe9d1, 0xdbb3, 0xbf77,
0xe971, 0xdaf3, 0xbdf7, 0x73ff, 0xe7fe, 0xc7ed, 0x87cb, 0x787,
0x62e7, 0xc5ce, 0x838d, 0xf0b, 0x1e16, 0x3c2c, 0x7858, 0xf0b0,
0x93d3, 0x2fb7, 0x5f6e, 0xbedc, 0x75a9, 0xeb52, 0xdeb5, 0xb57b,
0xe485, 0xc11b, 0x8a27, 0x1c5f, 0x38be, 0x717c, 0xe2f8, 0xcde1,
0xd341, 0xae93, 0x5537, 0xaa6e, 0x5ccd, 0xb99a, 0x7b25, 0xf64a,
0x535e, 0xa6bc, 0x4569, 0x8ad2, 0x1db5, 0x3b6a, 0x76d4, 0xeda8,
0xbba8, 0x7f41, 0xfe82, 0xf515, 0xe23b, 0xcc67, 0x90df, 0x29af,
0x29f9, 0x53f2, 0xa7e4, 0x47d9, 0x8fb2, 0x1775, 0x2eea, 0x5dd4,
0x6a67, 0xd4ce, 0xa18d, 0x4b0b, 0x9616, 0x243d, 0x487a, 0x90f4,
0x17d3, 0x2fa6, 0x5f4c, 0xbe98, 0x7521, 0xea42, 0xdc95, 0xb13b,
0xe401, 0xc013, 0x8837, 0x187f, 0x30fe, 0x61fc, 0xc3f8, 0x8fe1,
0x116d, 0x22da, 0x45b4, 0x8b68, 0x1ec1, 0x3d82, 0x7b04, 0xf608,
0xb8f2, 0x79f5, 0xf3ea, 0xefc5, 0xd79b, 0xa727, 0x465f, 0x8cbe,
0xd425, 0xa05b, 0x48a7, 0x914e, 0x2a8d, 0x551a, 0xaa34, 0x5c79,
0x767b, 0xecf6, 0xd1fd, 0xabeb, 0x5fc7, 0xbf8e, 0x770d, 0xee1a,
0xcd22, 0x9255, 0x2cbb, 0x5976, 0xb2ec, 0x6dc9, 0xdb92, 0xbf35,
0x2dd, 0x5ba, 0xb74, 0x16e8, 0x2dd0, 0x5ba0, 0xb740, 0x6691,
0xd6a, 0x1ad4, 0x35a8, 0x6b50, 0xd6a0, 0xa551, 0x42b3, 0x8566,
0xcc51, 0x90b3, 0x2977, 0x52ee, 0xa5dc, 0x43a9, 0x8752, 0x6b5,
0x43c0, 0x8780, 0x711, 0xe22, 0x1c44, 0x3888, 0x7110, 0xe220,
0xc64f, 0x848f, 0x10f, 0x21e, 0x43c, 0x878, 0x10f0, 0x21e0,
0xba35, 0x7c7b, 0xf8f6, 0xf9fd, 0xfbeb, 0xffc7, 0xf79f, 0xe72f,
0x6694, 0xcd28, 0x9241, 0x2c93, 0x5926, 0xb24c, 0x6c89, 0xd912,
0xd2cb, 0xad87, 0x531f, 0xa63e, 0x446d, 0x88da, 0x19a5, 0x334a,
0x780d, 0xf01a, 0xe825, 0xd85b, 0xb8a7, 0x795f, 0xf2be, 0xed6d,
0xdb9d, 0xbf2b, 0x7647, 0xec8e, 0xd10d, 0xaa0b, 0x5c07, 0xb80e,
0x4fb7, 0x9f6e, 0x36cd, 0x6d9a, 0xdb34, 0xbe79, 0x74e3, 0xe9c6,
0xc17b, 0x8ae7, 0x1ddf, 0x3bbe, 0x777c, 0xeef8, 0xd5e1, 0xa3d3,
0xcd95, 0x933b, 0x2e67, 0x5cce, 0xb99c, 0x7b29, 0xf652, 0xe4b5,
0xc3e9, 0x8fc3, 0x1797, 0x2f2e, 0x5e5c, 0xbcb8, 0x7161, 0xe2c2,
0x7a0c, 0xf418, 0xe021, 0xc853, 0x98b7, 0x397f, 0x72fe, 0xe5fc,
0xca16, 0x9c3d, 0x306b, 0x60d6, 0xc1ac, 0x8b49, 0x1e83, 0x3d06,
0x757d, 0xeafa, 0xdde5, 0xb3db, 0x6fa7, 0xdf4e, 0xb68d, 0x650b,
0xa817, 0x583f, 0xb07e, 0x68ed, 0xd1da, 0xaba5, 0x5f5b, 0xbeb6,
0x6496, 0xc92c, 0x9a49, 0x3c83, 0x7906, 0xf20c, 0xec09, 0xd003,
0xf1db, 0xeba7, 0xdf5f, 0xb6af, 0x654f, 0xca9e, 0x9d2d, 0x324b,
0x68af, 0xd15e, 0xaaad, 0x5d4b, 0xba96, 0x7d3d, 0xfa7a, 0xfce5,
0x5d95, 0xbb2a, 0x7e45, 0xfc8a, 0xf105, 0xea1b, 0xdc27, 0xb05f,
0xc379, 0x8ee3, 0x15d7, 0x2bae, 0x575c, 0xaeb8, 0x5561, 0xaac2,
0xee85, 0xd51b, 0xa227, 0x4c5f, 0x98be, 0x396d, 0x72da, 0xe5b4,
0xd34b, 0xae87, 0x551f, 0xaa3e, 0x5c6d, 0xb8da, 0x79a5, 0xf34a,
0xfc04, 0xf019, 0xe823, 0xd857, 0xb8bf, 0x796f, 0xf2de, 0xedad,
0x46d8, 0x8db0, 0x1371, 0x26e2, 0x4dc4, 0x9b88, 0x3f01, 0x7e02,
0x5a83, 0xb506, 0x621d, 0xc43a, 0x8065, 0x8db, 0x11b6, 0x236c,
0xb6c9, 0x6583, 0xcb06, 0x9e1d, 0x342b, 0x6856, 0xd0ac, 0xa949,
0x5b7b, 0xb6f6, 0x65fd, 0xcbfa, 0x9fe5, 0x37db, 0x6fb6, 0xdf6c,
0xcd0f, 0x920f, 0x2c0f, 0x581e, 0xb03c, 0x6869, 0xd0d2, 0xa9b5,
0xf83a, 0xf865, 0xf8db, 0xf9a7, 0xfb5f, 0xfeaf, 0xf54f, 0xe28f,
0x9e21, 0x3453, 0x68a6, 0xd14c, 0xaa89, 0x5d03, 0xba06, 0x7c1d,
0x3015, 0x602a, 0xc054, 0x88b9, 0x1963, 0x32c6, 0x658c, 0xcb18,
0x471c, 0x8e38, 0x1461, 0x28c2, 0x5184, 0xa308, 0x4e01, 0x9c02,
0xdaaa, 0xbd45, 0x729b, 0xe536, 0xc27d, 0x8ceb, 0x11c7, 0x238e,
0xa8a, 0x1514, 0x2a28, 0x5450, 0xa8a0, 0x5951, 0xb2a2, 0x6d55,
0x2b58, 0x56b0, 0xad60, 0x52d1, 0xa5a2, 0x4355, 0x86aa, 0x545,
0xdee6, 0xb5dd, 0x63ab, 0xc756, 0x86bd, 0x56b, 0xad6, 0x15ac,
0x82e6, 0xddd, 0x1bba, 0x3774, 0x6ee8, 0xddd0, 0xb3b1, 0x6f73,
0x82ba, 0xd65, 0x1aca, 0x3594, 0x6b28, 0xd650, 0xa4b1, 0x4173,
0x1a53, 0x34a6, 0x694c, 0xd298, 0xad21, 0x5253, 0xa4a6, 0x415d,
0x6004, 0xc008, 0x8801, 0x1813, 0x3026, 0x604c, 0xc098, 0x8921,
0x4644, 0x8c88, 0x1101, 0x2202, 0x4404, 0x8808, 0x1801, 0x3002,
0x466, 0x8cc, 0x1198, 0x2330, 0x4660, 0x8cc0, 0x1191, 0x2322,
0x634, 0xc68, 0x18d0, 0x31a0, 0x6340, 0xc680, 0x8511, 0x233,
0x77a1, 0xef42, 0xd695, 0xa53b, 0x4267, 0x84ce, 0x18d, 0x31a,
0xb4f4, 0x61f9, 0xc3f2, 0x8ff5, 0x17fb, 0x2ff6, 0x5fec, 0xbfd8,
0xb11f, 0x6a2f, 0xd45e, 0xa0ad, 0x494b, 0x9296, 0x2d3d, 0x5a7a,
0xe8c7, 0xd99f, 0xbb2f, 0x7e4f, 0xfc9e, 0xf12d, 0xea4b, 0xdc87,
0xb25b, 0x6ca7, 0xd94e, 0xba8d, 0x7d0b, 0xfa16, 0xfc3d, 0xf06b,
0xece4, 0xd1d9, 0xaba3, 0x5f57, 0xbeae, 0x754d, 0xea9a, 0xdd25,
0xa1c6, 0x4b9d, 0x973a, 0x2665, 0x4cca, 0x9994, 0x3b39, 0x7672,
0xa39b, 0x4f27, 0x9e4e, 0x348d, 0x691a, 0xd234, 0xac79, 0x50e3,
0x2af9, 0x55f2, 0xabe4, 0x5fd9, 0xbfb2, 0x7775, 0xeeea, 0xd5c5,
0x6a64, 0xd4c8, 0xa181, 0x4b13, 0x9626, 0x245d, 0x48ba, 0x9174,
0x2548, 0x4a90, 0x9520, 0x2251, 0x44a2, 0x8944, 0x1a99, 0x3532,
0xce69, 0x94c3, 0x2197, 0x432e, 0x865c, 0x4a9, 0x952, 0x12a4,
0xfe09, 0xf403, 0xe017, 0xc83f, 0x986f, 0x38cf, 0x719e, 0xe33c,
0x9d3f, 0x326f, 0x64de, 0xc9bc, 0x9b69, 0x3ec3, 0x7d86, 0xfb0c,
0xc9e9, 0x9bc3, 0x3f97, 0x7f2e, 0xfe5c, 0xf4a9, 0xe143, 0xca97,
0x7a06, 0xf40c, 0xe009, 0xc803, 0x9817, 0x383f, 0x707e, 0xe0fc,
0x654c, 0xca98, 0x9d21, 0x3253, 0x64a6, 0xc94c, 0x9a89, 0x3d03,
0x880d, 0x180b, 0x3016, 0x602c, 0xc058, 0x88a1, 0x1953, 0x32a6,
0xdb6d, 0xbecb, 0x7587, 0xeb0e, 0xde0d, 0xb40b, 0x6007, 0xc00e,
0xb838, 0x7861, 0xf0c2, 0xe995, 0xdb3b, 0xbe67, 0x74df, 0xe9be,
0xbd73, 0x72f7, 0xe5ee, 0xc3cd, 0x8f8b, 0x1707, 0x2e0e, 0x5c1c,
0x41a1, 0x8342, 0xe95, 0x1d2a, 0x3a54, 0x74a8, 0xe950, 0xdab1,
0xb4c2, 0x6195, 0xc32a, 0x8e45, 0x149b, 0x2936, 0x526c, 0xa4d8,
0xe5aa, 0xc345, 0x8e9b, 0x1527, 0x2a4e, 0x549c, 0xa938, 0x5a61,
0xab5, 0x156a, 0x2ad4, 0x55a8, 0xab50, 0x5eb1, 0xbd62, 0x72d5,
0xe22c, 0xcc49, 0x9083, 0x2917, 0x522e, 0xa45c, 0x40a9, 0x8152,
0xeb8c, 0xdf09, 0xb603, 0x6417, 0xc82e, 0x984d, 0x388b, 0x7116,
0x4e8f, 0x9d1e, 0x322d, 0x645a, 0xc8b4, 0x9979, 0x3ae3, 0x75c6,
0x7cb1, 0xf962, 0xfad5, 0xfdbb, 0xf367, 0xeedf, 0xd5af, 0xa34f,
0xa47e, 0x40ed, 0x81da, 0xba5, 0x174a, 0x2e94, 0x5d28, 0xba50,
0x9a5d, 0x3cab, 0x7956, 0xf2ac, 0xed49, 0xd283, 0xad17, 0x523f,
0x89fa, 0x1be5, 0x37ca, 0x6f94, 0xdf28, 0xb641, 0x6493, 0xc926,
0x585c, 0xb0b8, 0x6961, 0xd2c2, 0xad95, 0x533b, 0xa676, 0x44fd,
0x98b1, 0x3973, 0x72e6, 0xe5cc, 0xc389, 0x8f03, 0x1617, 0x2c2e,
0xa49a, 0x4125, 0x824a, 0xc85, 0x190a, 0x3214, 0x6428, 0xc850,
0x3b77, 0x76ee, 0xeddc, 0xd3a9, 0xaf43, 0x5697, 0xad2e, 0x524d,
0x703, 0xe06, 0x1c0c, 0x3818, 0x7030, 0xe060, 0xc8d1, 0x99b3,
0x329c, 0x6538, 0xca70, 0x9cf1, 0x31f3, 0x63e6, 0xc7cc, 0x8789,
0x5ed7, 0xbdae, 0x734d, 0xe69a, 0xc525, 0x825b, 0xca7, 0x194e,
0xa26c, 0x4cc9, 0x9992, 0x3b35, 0x766a, 0xecd4, 0xd1b9, 0xab63,
0xa9c8, 0x5b81, 0xb702, 0x6615, 0xcc2a, 0x9045, 0x289b, 0x5136,
0x4aed, 0x95da, 0x23a5, 0x474a, 0x8e94, 0x1539, 0x2a72, 0x54e4,
0x3ca1, 0x7942, 0xf284, 0xed19, 0xd223, 0xac57, 0x50bf, 0xa17e,
0xb4bf, 0x616f, 0xc2de, 0x8dad, 0x134b, 0x2696, 0x4d2c, 0x9a58,
0x4dc8, 0x9b90, 0x3f31, 0x7e62, 0xfcc4, 0xf199, 0xeb23, 0xde57,
0x4a09, 0x9412, 0x2035, 0x406a, 0x80d4, 0x9b9, 0x1372, 0x26e4,
0x9d8b, 0x3307, 0x660e, 0xcc1c, 0x9029, 0x2843, 0x5086, 0xa10c,
0x3a46, 0x748c, 0xe918, 0xda21, 0xbc53, 0x70b7, 0xe16e, 0xcacd,
0x2708, 0x4e10, 0x9c20, 0x3051, 0x60a2, 0xc144, 0x8a99, 0x1d23,
0x8c6f, 0x10cf, 0x219e, 0x433c, 0x8678, 0x4e1, 0x9c2, 0x1384,
0x9b7d, 0x3eeb, 0x7dd6, 0xfbac, 0xff49, 0xf683, 0xe517, 0xc23f,
0xa8f9, 0x59e3, 0xb3c6, 0x6f9d, 0xdf3a, 0xb665, 0x64db, 0xc9b6,
0x6ae6, 0xd5cc, 0xa389, 0x4f03, 0x9e06, 0x341d, 0x683a, 0xd074,
0x8252, 0xcb5, 0x196a, 0x32d4, 0x65a8, 0xcb50, 0x9eb1, 0x3573,
0x7115, 0xe22a, 0xcc45, 0x909b, 0x2927, 0x524e, 0xa49c, 0x4129,
0x475d, 0x8eba, 0x1565, 0x2aca, 0x5594, 0xab28, 0x5e41, 0xbc82,
0x8927, 0x1a5f, 0x34be, 0x697c, 0xd2f8, 0xade1, 0x53d3, 0xa7a6,
0x5534, 0xaa68, 0x5cc1, 0xb982, 0x7b15, 0xf62a, 0xe445, 0xc09b,
0x77f2, 0xefe4, 0xd7d9, 0xa7a3, 0x4757, 0x8eae, 0x154d, 0x2a9a,
0xd4ea, 0xa1c5, 0x4b9b, 0x9736, 0x267d, 0x4cfa, 0x99f4, 0x3bf9,
0x4880, 0x9100, 0x2a11, 0x5422, 0xa844, 0x5899, 0xb132, 0x6a75,
0x8440, 0x91, 0x122, 0x244, 0x488, 0x910, 0x1220, 0x2440,
0x4280, 0x8500, 0x211, 0x422, 0x844, 0x1088, 0x2110, 0x4220,
0x844a, 0x85, 0x10a, 0x214, 0x428, 0x850, 0x10a0, 0x2140,
0xedda, 0xd3a5, 0xaf5b, 0x56a7, 0xad4e, 0x528d, 0xa51a, 0x4225,
0x793a, 0xf274, 0xecf9, 0xd1e3, 0xabd7, 0x5fbf, 0xbf7e, 0x76ed,
0x9ea0, 0x3551, 0x6aa2, 0xd544, 0xa299, 0x4d23, 0x9a46, 0x3c9d,
0xa594, 0x4339, 0x8672, 0x4f5, 0x9ea, 0x13d4, 0x27a8, 0x4f50,
0xd208, 0xac01, 0x5013, 0xa026, 0x485d, 0x90ba, 0x2965, 0x52ca,
0x8c9a, 0x1125, 0x224a, 0x4494, 0x8928, 0x1a41, 0x3482, 0x6904,
0x3b5f, 0x76be, 0xed7c, 0xd2e9, 0xadc3, 0x5397, 0xa72e, 0x464d,
0xaa49, 0x5c83, 0xb906, 0x7a1d, 0xf43a, 0xe065, 0xc8db, 0x99a7,
0xdf6f, 0xb6cf, 0x658f, 0xcb1e, 0x9e2d, 0x344b, 0x6896, 0xd12c,
0x9b2e, 0x3e4d, 0x7c9a, 0xf934, 0xfa79, 0xfce3, 0xf1d7, 0xebbf,
0xc8e7, 0x99df, 0x3baf, 0x775e, 0xeebc, 0xd569, 0xa2c3, 0x4d97,
0x9379, 0x2ee3, 0x5dc6, 0xbb8c, 0x7f09, 0xfe12, 0xf435, 0xe07b,
0xeed5, 0xd5bb, 0xa367, 0x4edf, 0x9dbe, 0x336d, 0x66da, 0xcdb4,
0x81ce, 0xb8d, 0x171a, 0x2e34, 0x5c68, 0xb8d0, 0x79b1, 0xf362,
0x2ff3, 0x5fe6, 0xbfcc, 0x7789, 0xef12, 0xd635, 0xa47b, 0x40e7,
0xc53b, 0x8267, 0xcdf, 0x19be, 0x337c, 0x66f8, 0xcdf0, 0x93f1,
0x8f95, 0x173b, 0x2e76, 0x5cec, 0xb9d8, 0x7ba1, 0xf742, 0xe695,
0xc3ab, 0x8f47, 0x169f, 0x2d3e, 0x5a7c, 0xb4f8, 0x61e1, 0xc3c2,
0x1b1a, 0x3634, 0x6c68, 0xd8d0, 0xb9b1, 0x7b73, 0xf6e6, 0xe5dd,
0xbfc0, 0x7791, 0xef22, 0xd655, 0xa4bb, 0x4167, 0x82ce, 0xd8d,
0xc6b3, 0x8577, 0x2ff, 0x5fe, 0xbfc, 0x17f8, 0x2ff0, 0x5fe0,
0x87d6, 0x7bd, 0xf7a, 0x1ef4, 0x3de8, 0x7bd0, 0xf7a0, 0xe751,
0xb33c, 0x6e69, 0xdcd2, 0xb1b5, 0x6b7b, 0xd6f6, 0xa5fd, 0x43eb,
0xfb5c, 0xfea9, 0xf543, 0xe297, 0xcd3f, 0x926f, 0x2ccf, 0x599e,
0x9812, 0x3835, 0x706a, 0xe0d4, 0xc9b9, 0x9b63, 0x3ed7, 0x7dae,
0x330b, 0x6616, 0xcc2c, 0x9049, 0x2883, 0x5106, 0xa20c, 0x4c09,
0xbee0, 0x75d1, 0xeba2, 0xdf55, 0xb6bb, 0x6567, 0xcace, 0x9d8d,
0xe7b0, 0xc771, 0x86f3, 0x5f7, 0xbee, 0x17dc, 0x2fb8, 0x5f70,
0xb56c, 0x62c9, 0xc592, 0x8335, 0xe7b, 0x1cf6, 0x39ec, 0x73d8,
0xa9df, 0x5baf, 0xb75e, 0x66ad, 0xcd5a, 0x92a5, 0x2d5b, 0x5ab6,
0x2ed3, 0x5da6, 0xbb4c, 0x7e89, 0xfd12, 0xf235, 0xec7b, 0xd0e7,
0xe438, 0xc061, 0x88d3, 0x19b7, 0x336e, 0x66dc, 0xcdb8, 0x9361,
0xbd2f, 0x724f, 0xe49e, 0xc12d, 0x8a4b, 0x1c87, 0x390e, 0x721c,
];
pub fn fix_parity_errors(frame: &mut [u8], crc: u16, parity_error_offsets: &[usize]) -> bool {
if let Some((&first, rest)) = parity_error_offsets.split_first() {
for i in 0..8 {
let new_crc = crc ^ SYNDROM[i + 8 * (frame.len() - first + 1)];
if fix_parity_errors(frame, new_crc, rest) {
frame[first] ^= 1 << i;
return true;
}
}
false
} else {
if crc == 0 {
return true;
}
SYNDROM[..16].contains(&crc)
}
}
pub fn fix_double_error(frame: &mut [u8], crc: u16) -> bool {
if SYNDROM[..16].contains(&crc) {
return true;
}
let len = frame.len();
for (k, byte) in frame.iter_mut().enumerate() {
let bo = 8 * (len - k + 1);
for i in 0..8 {
for j in 0..8 {
if i == j {
continue;
}
if crc ^ SYNDROM[i + bo] ^ SYNDROM[j + bo] == 0 {
*byte ^= 1 << i;
*byte ^= 1 << j;
return true;
}
}
}
}
false
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
use crate::crc;
fn frame_with_bcs(txt: &[u8]) -> (Vec<u8>, u8, u8) {
let bcs = crc::compute(txt);
#[allow(clippy::cast_possible_truncation)]
let lo = (bcs & 0xff) as u8;
#[allow(clippy::cast_possible_truncation)]
let hi = ((bcs >> 8) & 0xff) as u8;
(txt.to_vec(), lo, hi)
}
fn crc_with_bcs(txt: &[u8], bcs_lo: u8, bcs_hi: u8) -> u16 {
let mut full = txt.to_vec();
full.push(bcs_lo);
full.push(bcs_hi);
crc::compute(&full)
}
#[test]
fn syndrom_table_has_expected_size() {
assert_eq!(SYNDROM.len(), 1936);
assert_eq!(SYNDROM.len() % 8, 0);
}
#[test]
fn syndrom_first_row_matches_c() {
assert_eq!(SYNDROM[0], 0x1189);
assert_eq!(SYNDROM[1], 0x2312);
assert_eq!(SYNDROM[2], 0x4624);
assert_eq!(SYNDROM[3], 0x8c48);
assert_eq!(SYNDROM[4], 0x1081);
assert_eq!(SYNDROM[5], 0x2102);
assert_eq!(SYNDROM[6], 0x4204);
assert_eq!(SYNDROM[7], 0x8408);
}
#[test]
fn syndrom_last_row_matches_c() {
assert_eq!(SYNDROM[1928], 0xbd2f);
assert_eq!(SYNDROM[1929], 0x724f);
assert_eq!(SYNDROM[1930], 0xe49e);
assert_eq!(SYNDROM[1931], 0xc12d);
assert_eq!(SYNDROM[1932], 0x8a4b);
assert_eq!(SYNDROM[1933], 0x1c87);
assert_eq!(SYNDROM[1934], 0x390e);
assert_eq!(SYNDROM[1935], 0x721c);
}
#[test]
fn syndrom_is_a_pure_static_table() {
assert_ne!(SYNDROM[1935], 0);
}
#[test]
fn single_bit_flip_in_last_byte_recovers() {
let original = b"HELLO ACARS!!".to_vec();
let (txt, bcs_lo, bcs_hi) = frame_with_bcs(&original);
assert_eq!(crc_with_bcs(&txt, bcs_lo, bcs_hi), 0);
let mut frame = txt.clone();
let bit = 3_usize;
let pos = frame.len() - 1;
frame[pos] ^= 1 << bit;
let crc_corrupted = crc_with_bcs(&frame, bcs_lo, bcs_hi);
assert_ne!(crc_corrupted, 0, "corruption did not change CRC");
let recovered = fix_parity_errors(&mut frame, crc_corrupted, &[pos]);
assert!(recovered, "fix_parity_errors didn't find the bit flip");
assert_eq!(frame, txt, "frame not restored after fix");
}
#[test]
fn no_correction_when_no_parity_errors_and_zero_crc() {
let mut frame = b"clean".to_vec();
assert!(fix_parity_errors(&mut frame, 0, &[]));
}
#[test]
fn fix_double_error_handles_two_bit_flip_in_one_byte() {
let original = b"DOUBLE ERROR!".to_vec();
let (txt, bcs_lo, bcs_hi) = frame_with_bcs(&original);
let mut frame = txt.clone();
let pos = frame.len() / 2;
frame[pos] ^= 0b0000_1001;
let crc_corrupted = crc_with_bcs(&frame, bcs_lo, bcs_hi);
assert_ne!(crc_corrupted, 0, "corruption did not change CRC");
let recovered = fix_double_error(&mut frame, crc_corrupted);
assert!(recovered, "fix_double_error didn't find the pair");
assert_eq!(frame, txt, "frame not restored");
}
}