假设我们有一大块数据来自具有以下属性的数据传输介质:
这种情况下最好的错误检测和错误纠正算法是什么?当然,它总是在每块有用数据量和成功验证(纠正)概率之间进行折衷。
答案 0 :(得分:1)
这是尝试从http://en.wikipedia.org/wiki/Frame_Relay收集一些想法。
使用固定标头01110启动每个64位块。如果您有更多标头信息(例如序列号或交替位标志,校验和......),您可以安排从不出现位模式01110。对于任意数据,将0111的任何出现替换为01111 - 这意味着有效数据速率现在取决于基础数据。让这一层的数据提供者确保数据几乎是随机的,例如通过应用http://en.wikipedia.org/wiki/Randomizer。我认为你的总数据丢失大约是6位,这与描述0..63移位所需的6位相符。
在接收器中,查找01110以标记块的真正开始。如果你没有看到一个这样的模式,你知道这个块已经出现乱码。我认为至少需要两位误差才能销毁现有的01110并生成假的。
导致块错位的Garbles看起来不像典型的bit garbles,因此CRC错误率计算不会开箱即用。我会在每个块中包含一个非CRC校验和 - 可能是一个检查计算mod 31或mod 961,以避免禁用的5位模式01110,虽然取决于什么邻接,你可能需要更严格。与多项式CRC不同,未检测到错误的可能性大约为1比31或1比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。
答案 1 :(得分:1)
这只是对完整问题的部分答案,因为我不会回答如何确定起点。请参阅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结合使用(由于索引脚印,数据大小可能会增加。)
如果接收器不知道循环周期,有两种方法可以解决:
猜猜长度并进行投票。继续这样做不同的长度,直到你得到一个非常高的相关长度。 (每个比特的高置信水平)
对接收的数据执行傅里叶变换。这将立即显示假设数据不太嘈杂的时间段。