我正在根据 edc_ecc.c web github 文件将我在这个答案中找到的内容作为我取得的进展。RSL12 是 GF(2^8),多项式 x^8 + x^4 + x^3 + x^2 + 1 => 十六进制 11d。字段中的所有非零数字都可以视为 hex 02 的幂。
十六进制的 P 生成多项式是:
(x+01)(x+02)(x+04)(x+08) = 01 x^4 + 0f x^3 + 36 x^2 + 78 x + 40
如果您查看 AP[...][31] 的 4 个条目,您会看到值 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 个字节,但它们显然是错误的。
有一种解决方法,使用 4 擦除解码,将位置 12 到 15 标记为擦除(xx xx xx xx)进行 Q 编码:
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 字节的奇偶校验。应删除 AP[...][32] 每一行的前 4 个值,因此它变为 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);
}
回应评论。为了生成 AQ,我使用擦除校正来生成 24 组奇偶校验:
01 00 00 00 00 00 00 00 00 00 00 00 69 60 bf b7 00 00 00 00 00 00 00 00 00 00 00 00
00 01 00 00 00 00 00 00 00 00 00 00 49 f9 fa 4b 00 00 00 00 00 00 00 00 00 00 00 00
...
00 00 00 00 00 00 00 00 00 00 00 00 9e a7 ab 93 00 00 00 00 00 00 00 00 00 00 01 00
00 00 00 00 00 00 00 00 00 00 00 00 1f 3b cf ea 00 00 00 00 00 00 00 00 00 00 00 01
AQ[][ 0] = hex log2{69 60 bf b7} = decimal {058 030 162 158}
AQ[][ 1] = hex log2{49 f9 fa 4b} = decimal {152 214 244 179}
...
AQ[][22] = hex log2{9e a7 ab 93} = decimal {137 205 178 119}
AQ[][23] = hex log2{1f 3b cf ea} = decimal {113 120 246 022}
另一种方法是使用全长 255 字节码字全为零,除了在适当位置模 255 处设置为 01 的一个字节,以标准方式生成奇偶校验,奇偶校验 = msg * x^4 % 生成器。这会生成超出其目标位置 16 个字节的奇偶校验,因此偏移量需要调整 255-16 = +239 模 255 以产生目标奇偶校验:
255_byte_message_offset = 28_byte_message_offset + 239 % 255:
msg[239] = 01 => parities = 69 60 bf b7
msg[240] = 01 => parities = 49 f9 fa 4b
...
msg[010] = 01 => parities = 9e a7 ab 93
msg[011] = 01 => parities = 1f 3b cf ea