我迟到了这个问题,但以防万一这可以帮助其他人:
在数字计算机上实现 Reed Solomon 的最简单和最常用的方法是使用 RS(255、223)CCSDS 编码。这种编码由 CCSDS 指定,几十年来一直广泛用于深空探测器和卫星等硬件中。
RS(255、223)具有以下特点:
- 每个符号有 2^8 种组合(J = 8),所以每个符号都是一个字节。
- 每个码字有 2^8 - 1 个符号,因此每个编码块的长度为 255 个字节。
- 每个块可以编码的数据量是 223 字节
- 每个块包含 32 字节的 FEC 奇偶校验数据(223 数据字节 + 32 奇偶校验字节 = 255 字节块)
- 在不知道擦除(错误位置)的情况下,每个块最多可以纠正 16 个错误(E = 16,这始终等于奇偶校验字节数 / 2)
- 当错误位置已知时,每个块最多可以纠正 32 个错误(这始终等于奇偶校验字节数)
- CCSDS 指定使用 1 + X + X^2 + X^7 + X^8 的场生成多项式,第一个连续根 = 112 的代码生成器,以及 11 的原始元素。
- CCSDS 还指定了双基多项式表示,以简化专用硬件中的编码器/解码器实现。这是 RS(255、223)的许多现代软件实现中省略的一项功能,因为它对通用 CPU 没有实际用途,但在与旧硬件通信时仍然需要它。一定要弄清楚你是否需要这个 - 它可以通过在编码/解码之前/之后通过查找表运行正常多项式输出来完成。
一个 255 个符号的码字可以交织四次 (I = 4),从而得到 892 的总块大小。这样做可以分散每个码字之间的传输突发错误,从而增加成功码字校正的机会。有关详细信息,请参阅下面链接的规范。
我不确定“128 字节码字”是什么意思,但它可能与填充有关:
由于 2^8 的符号大小是一个相当硬的约束,每个码字必须是 255 字节长。但是,如果你不能一次性发送一个 255 字节的块,或者更喜欢更多的错误保护,可以使用填充来有效地缩短 255 字节的块。
填充的工作原理是简单地将 223 个数据字节中的一些定义为填充而不是数据。填充只是发送者和接收者提前知道的一些固定值序列(CCSDS 将其称为“虚拟填充”)。编码时,将一小部分数据添加到数据的开头以形成完整的 223 个“数据”字节,然后将这些数据正常输入编码器。编码后,填充从块的开头被剥离,产生一个更短的块(或者更确切地说,数据和奇偶校验可能被复制到一个更小的数组中)。然后传送。
解码时,填充会在解码器运行之前插入到块的开头。由于填充序列具有已知的固定值,因此这些字节包含错误的可能性为 0%。这意味着 16 字节的错误保护将转移到块的其余部分。
因此,要从 RS(255、223)获取 127 字节块,您可以从原始 223 字节中填充除 95 字节之外的所有数据,然后对其进行编码。您的块将如下所示:
填充[128] + 数据[95] + 奇偶校验[32] = 255 字节
然后在发送块之前删除填充:
数据[95] + 奇偶校验[32] = 127 字节
最后在解码器端,在解码之前添加填充:
填充[128] + 数据[95] + 奇偶校验[32] = 255 字节
这实际上是一个 RS(127, 95) 代码,每 127 个字节块提供 16 个字节的 FEC。
CCSDS 标准规定虚拟填充:
- 必须由全零组成
- 不得传送
- 特定物理通道上的任务阶段的长度不得更改
- 只能插入到代码块的开头
- 只能以 8I 位的整数倍插入。
如果您正在与之交谈的旧设备也严格实施这些,您只需要遵守这些(如果它是严格的 CCSDS,它会)。
对于 RS(255、223)的 C# 实现,我在这里有一个小库:
https://github.com/crozone/ReedSolomonCCSDS
这是基于 Phil Karn 的 C 实现,该实现随处可见,包括 GNURadio 和 Android OS。
CCSDS 摘要:“TM 同步和信道编码——概念和原理摘要”(第 5 节)
https://public.ccsds.org/pubs/130x1g2.pdf
CCSDS 参考:“TM 同步和通道编码”第 4 节。
https://public.ccsds.org/Pubs/131x0b3e1.pdf