【问题标题】:Error detection and error correction algorithm错误检测和纠错算法
【发布时间】:2011-11-10 04:44:07
【问题描述】:

假设我们有一大块来自数据传输介质的数据,具有以下属性:

  • 总块大小为 8 字节
  • 数据传输不可靠,因此可能出现多个位错误。
  • 数据传输是循环的,数据块的开始是未知的。例如,代码 0123456789ABCDEF3456789ABCDEF012 (0123456789ABCDEF 02468ACF13579BDE (0123456789ABCDEF

什么是这种情况下最好的错误检测和纠错算法?当然,它总是在每个块的有用数据量和成功验证(纠正)概率之间进行折衷。

【问题讨论】:

  • 错误检测/纠正由您可以承受的错误量定义。它是什么? 1 个?
  • 我想考虑不同的方法:0 位(校验和)、1 位、2 位或更多。
  • 周期的(最大)长度是多少?如果你不知道,你就迷路了。
  • @Philip:“总块大小为 8 个字节”。位粒度使这很棘手。如果旋转与字节对齐,那么我可以想办法用 (10,9) Reed-Solomon 进行检测,并用 (11,9) Reed-Solomon 进行至少 1 位校正。另一方面,如果数据被重复发送(就像在那个循环中一遍又一遍地发送),这本身就已经足够冗余了,你可以只用一个简单的傅立叶变换就可以了。
  • 没关系傅立叶变换。在这样的重复循环情况下,3 个循环足以获得 3 位 ECC,因此傅立叶变换是多余的。它也没有显示旋转。

标签: algorithm checksum error-correction error-detection


【解决方案1】:

这是从http://en.wikipedia.org/wiki/Frame_Relay 中汲取的一些想法的尝试。

从每个 64 位块的固定标头 01110 开始。如果您有更多标头信息(例如序列号或交替位标志、校验和...),您可能可以安排位模式 01110 永远不会出现。对于任意数据,将任何出现的 0111 替换为 01111 - 这意味着有效数据速率现在取决于基础数据。让这一层的数据提供者确保数据几乎是随机的,例如通过应用http://en.wikipedia.org/wiki/Randomizer。我认为您在这里的总数据丢失约为 6 位,这符合描述 0..63 移位所需的 6 位。

在接收器中,寻找 01110 来标记块的真正开始。如果你没有看到一个这样的模式,你就知道这个块已经乱码了。我认为破坏现有的 01110 并产生假的至少需要两位错误。

导致块未对齐的乱码看起来不像典型的位乱码,因此 CRC 错误率计算不会立即应用。我会在每个块中包含一个非 CRC 校验和——也许是一个计算 mod 31 或 mod 961 的校验,以避免被禁止的 5 位模式 01110,尽管取决于与之相邻的内容,您可能需要更加严格。与多项式 CRC 不同,未检测到错误的几率大约为 31 分之一或 961 分之一,并不能特别保证所有单个错误。

我认为您没有足够的空间来明智地进行每个块的纠错,但是您可以在每 M 个普通块之后包含 N 个纠错块,例如使用SECDED 向下应用列。你可能有例如57 个数据承载块,然后是 6 个纠错块,将每个有效载荷位位置视为承载 57 个数据位,然后是 6 个校验和位。如果错误倾向于破坏单个块的全部或不破坏,这应该很好用,例如通过导致块重新对齐失败。

评论后-

编辑

好的,通过一条连续传输的消息,您的带宽较少,但 cpu 相对较多。想到两件事:

1) 给定任何类型的校验和或对消息的其他约束,您可以通过例如实现一些有限的错误纠正。考虑所有单比特错误,翻转一些接收到的消息,并查看校验和现在是否有效。

2) 可以通过仅查看通过消息的 5 位窗口来检查消息是否符合上面建议的位填充方案。我认为即使您需要对其进行调整以使其在环绕时正常工作也是如此。这意味着可以通过可处理大小的 BDD 检查消息(Knuth 4A 第 7.1.4 节)。这意味着您可以统计符合比特填充方案的 64 位消息的数量,并在消息号和消息(同一部分)之间进行有效转换。因此,您可以使用此方案,而无需对要发送的数据进行潜在的随机化或最坏情况假设,只需将其视为 0..N 范围内的数字的编码(其中 N 将通过 BDD 计算)和64 位消息。事实上,不太优雅的是,我认为您可以使用具有 5 位状态的动态编程来代替 BDD。

【讨论】:

  • 在我的情况下,有一个无限传输的块。
【解决方案2】:

这只是完整问题的部分答案,因为我不会回答如何确定起点。请参阅 mcdowella 的答案。我本打算将其作为评论,但它太长了。

对于连续传输的消息,实际上不再需要任何纠错。即使发生一个位翻转(或一堆),它也不太可能影响正在传输的同一位的每个实例 - 特别是如果它永远重复。所以从这个意义上说,你的冗余因子是 N,随着广播的进行,N 接近无穷大。

因此,现在重建 64 位非常容易,因为您有很多样本要查看。假设接收器知道循环长度,您只需轮询流并计算 64 个位置中每个位置的每个位出现的次数。

所以说在 100 个完整的循环之后,你会得到:

Bit #    0s / 1s    Interpret bit as
Bit 0:  100 /   0        0
Bit 1:    0 / 100        1
Bit 2:   99 /   1        0
Bit 3:   98 /   2        0
Bit 4:    1 /  99        1
...
Bit 63:  96 /   4        0

根据这些样本,您可以统计出正确的位值是多少。接收者继续接收周期的时间越长,你的界限就越强。因此,如果传输了足够多的周期,您可以容忍任意高的错误率。

当然,这适用于任何周期长度 - 不仅仅是 64 位。因此,将此方法与 mcdowella 的方法结合使用(由于 index-foot-print,数据大小可能会增加)。

如果接收方不知道循环周期,有两种方法可以计算出来:

  1. 猜测长度并运行轮询。继续对不同的长度执行此操作,直到获得具有非常高相关性的长度。 (每个位的置信度高)

  2. 对接收到的数据执行傅里叶变换。假设数据不是太可笑的嘈杂,这将立即显示时间段。

【讨论】:

  • 很遗憾,无法等待 100 个样本。它太长了。我们最多可以等待 2-3 个样本。
猜你喜欢
  • 2013-08-19
  • 1970-01-01
  • 2011-08-05
  • 1970-01-01
  • 2012-08-21
  • 1970-01-01
  • 1970-01-01
  • 2013-02-23
  • 1970-01-01
相关资源
最近更新 更多