Я выкладываю то, что нахожу в этом ответе, когда делаю успехи, основываясь на файлах edc_ecc.c web github. RSL12 - это GF (2 ^ 8), полином x ^ 8 + x ^ 4 + x ^ 3 + x ^ 2 + 1 => hex 11d. Все ненулевые числа в поле можно считать степенями шестнадцатеричного числа 02.
Полином P-генератора в шестнадцатеричном виде:
(x+01)(x+02)(x+04)(x+08) = 01 x^4 + 0f x^3 + 36 x^2 + 78 x + 40
Если вы посмотрите на 4 записи для AP [...] [31], вы увидите значения 75, 249, 78, 6, это десятичные записи в шестнадцатеричном формате 0f, 36, 78, 40. Обратите внимание, что AP должна быть AP [4] [28] (не [4] [32]), исправление показано ниже.
Исходя из вашего (теперь удаленного) комментария, я "неинвертировал" Q в примерах, которые вы дали в исходном вопросе, и, используя мою собственную демонстрационную программу RS для вычисления паритетов P, теперь я получаю 00 00 00 00:
01 01 01 01 01 01 01 01 01 01 01 01 1a 91 b1 3a 01 01 01 01 01 01 01 01 01 01 01 01 00 00 00 00
a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 94 43 5a 8d a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 00 00 00 00
Полином Q-генератора такой же, как полином P-генератора. Он используется для RS (28,24), но байты четности находятся посередине, поэтому необходимо изменить обычное кодирование, как описано ниже.
AQ [] [] неправильно, используя AQ [3] [], чтобы получить Q [3], я получаю 69 вместо 3a:
01 01 01 01 01 01 01 01 01 01 01 01 -- -- -- 69 01 01 01 01 01 01 01 01 01 01 01 01
Кроме того, для AQ [0] определено только 21 байт, для AQ [1] определено только 22 байта, для AQ [2] определено только 23 байта, для AQ [3] определено 24 байта, но они, по-видимому, ошибочны .
Существует обходной путь, для декодирования Q используйте 4 декодирования стирания с местоположениями с 12 по 15, помеченными как стирания (xx xx xx xx):
01 01 01 01 01 01 01 01 01 01 01 01 xx xx xx xx 01 01 01 01 01 01 01 01 01 01 01 01
a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 xx xx xx xx a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5
После 4 коррекций стирания кодируются байты четности Q:
01 01 01 01 01 01 01 01 01 01 01 01 1a 91 b1 3a 01 01 01 01 01 01 01 01 01 01 01 01
a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 94 43 5a 8d a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5
Используя метод декодирования 4 стирания, я сгенерировал фиксированный AQ [] []:
static const unsigned char AQ[4][24] =
{{58,152,173,95,88,43,134,205,143,131,163,75,249,66,151,116,125,184,110,16,58,62,137,113},
{30,214,148,138,112,154,157,96,49,198,189,249,69,47,147,235,156,47,209,183,138,232,205,120},
{162,244,13,171,213,236,71,177,253,162,59,78,243,180,186,34,78,136,130,85,108,115,178,246},
{158,179,101,94,49,140,211,149,137,169,81,6,72,157,122,131,190,116,22,64,68,143,119,22}};
Однако, если вы планируете написать декодер (который исправляет стирания и / или ошибки), вы можете использовать тот же метод, что и я, используя 4-х стирающее декодирование вместо кодирования. Если я правильно помню, именно так некоторые ранние накопители DAT (цифровые аудиокассеты) реализовали это, поскольку у них также были байты четности в середине данных.
AP должно быть AP [4] [28]. P является RS (32,28), 28 байтов данных, используемых для генерации 4 байтов четностей. Первые 4 значения из каждой строки AP [...] [32] должны быть удалены, поэтому он становится AP [4] [28], а encode_L1_P () должен кодировать 28 байтов данных (исправление одной строки, как отмечалось) ниже).
static const unsigned char AP[4][28] =
{{249,142,180,197,5,155,153,132,143,244,101,76,102,155,203,104,58,152,173,95,88,43,134,205,143,131,163,75},
{205,252,218,199,202,41,136,106,119,238,193,103,123,242,83,178,30,214,148,138,112,154,157,96,49,198,189,249},
{67,11,131,40,7,41,80,147,151,17,245,253,208,66,228,116,162,244,13,171,213,236,71,177,253,162,59,78},
{148,186,203,11,161,159,138,149,250,107,82,108,161,209,110,64,158,179,101,94,49,140,211,149,137,169,81,6}};
encode_L1_P () требуется одна исправленная строка:
static int
encode_L1_P(inout)
unsigned char inout[L1_RAW + L1_Q + L1_P];
{
unsigned char *P;
int i;
P = inout + L1_RAW + L1_Q;
memset(P, 0, L1_P);
for (i = 0; i < L1_RAW + L1_Q; i++) { /* fix (remove + L1_P) */
unsigned char data;
data = inout[i];
if (data != 0) {
unsigned char base = rs_l12_log[data];
P[0] ^= rs_l12_alog[(base+AP[0][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
P[1] ^= rs_l12_alog[(base+AP[1][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
P[2] ^= rs_l12_alog[(base+AP[2][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
P[3] ^= rs_l12_alog[(base+AP[3][i]) % (unsigned)((1 << RS_L12_BITS)-1)];
}
}
return (0);
}