我研究有关CDROM原理的信息。在标准http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-130.pdf中 在第35页(pdf中的45)上,我看到了CIRC编码器。他有Q码和P码,这是由里德-所罗门算法计算出来的。 我尝试确认这一点并添加一些示例音频轨道(音频轨道未使用scramber作为数据轨道)一个填充为0x01模式,一个填充为0xA5(包中的CIRC中间字节不是位,我在F3帧中看到Q和P) 。在我用逻辑分析仪从CD(直接从Laser出来)中取出这个扇区后,用脚本解密。我有用于模式0x01的跟踪数据
S1 01 01 01 01 01 01 01 01 01 01 01 01 e5 6e 4e c5 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ff ff ff ff
S2 01 01 01 01 01 01 01 01 01 01 01 01 e5 6e 4e c5 01 01 01 01 01 01 01 01 01 01 01 01 01 01 ff ff ff ff
在此示例SYNC_1和SYNC_2中,第一个字节是子代码sumbol
对于具有0xA5模式的轨道
S1 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 6b bc a5 72 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ff ff ff ff
S1 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 6b bc a5 72 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 a5 ff ff ff ff
如果在CIRC上可以看到12-15字节的反向Q奇偶校验和28-32 P奇偶校验(第一个字节是其sybcode,他在F3处的加法运算)。
但是我找不到用于计算此字节的算法,我的数学技能很差。我尝试从cdrecord计算器,他做另一个代码,尝试另一个Reed-Solomon的实现,但我无法从此示例中获得相同的代码。 在哪里可以获取此代码的有效实现。
答案 0 :(得分:1)
我将根据edc_ecc.c Web github文件在此答案中找到的内容。 RSL12是GF(2 ^ 8),多项式x ^ 8 + x ^ 4 + x ^ 3 + x ^ 2 +1 =>十六进制11d。该字段中的所有非零数字都可以视为十六进制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 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);
}