是否可以使用CRC进行基本错误纠正?

时间:2010-09-24 15:30:54

标签: crc error-correction

我知道使用CRC的整个意图是进行错误检测,但我听到有人声称除了错误检测之外它还可用于进行基本的错误纠正。如果是这样的话,我很好奇,如果是这样,它有多强大?我的意思是,我们通常将CRC称为能够执行x位检测,但我很好奇它是否能够执行x位校正。如果是这样,这是如何工作的?感谢。

4 个答案:

答案 0 :(得分:10)

可以使用CRC进行单比特纠错。假设有一个CRC“寄存器”,并且具有一次向前和向后运行CRC算法的功能,忽略输入数据

int crc_forward(int old_value, int data_bit)
{
  if (old_value & 0x8000)
    return ((old_value ^ 0x8000) SHL 1) ^ 0x1021 ^ data_bit;
  else
    return (old_value SHL 1) ^ data_bit;
}

int crc_reverse(int old_value)
{
  if (old_value & 1)
    return (old_value SHR 1) ^ 0x8810;
  else
    return old_value SHR 1;
}

假设有一个数据包被计算,以便将crc初始化为某个值并为每个比特运行crc_forward(MSB优先)应该产生零。如果得到的CRC值不是零,则可以反向运行算法(忽略数据位),直到计算出的CRC值为1.这就是错误位的位置。

请注意,这种方法可能足以用于NAND闪存等软件纠错。为了有效地将其用于硬件纠错,人们必须能够延迟读取操作直到可以处理ECC,否则就需要一个“校正”值和位位置的表。

答案 1 :(得分:5)

您可以使用CRC进行多位纠错。查看维基百科,参考koopmans工作,CRC可以检测到其hamming_distance-1错误。汉明距离取决于有效载荷长度和使用的CRC多项式。因此,例如,0xBA0DC66B的Koopmans多项式可以在长达16360位的消息中检测多达5位的错误。前两条消息中描述的算法可以根据需要扩展到尽可能多的位,但时间会随着要修复的位数呈指数增长。

  1. 计算错误CRC = CRC_gotten ^ CRC_expected。
  2. 查看所有可能的1位消息(即全0,1和全0)(有要评估的message_length情况。注意这是BITS而不是BYTES),错误位是生成错误CRC的消息。
  3. 反转检测到的位以纠正错误。
  4. 如果找不到与错误CRC匹配的1位,请查看所有2位,3位直到你的hamming_distance-1。请注意,这会快速变慢,message_length的平方为2位,3位为5位,5位为5位。

答案 2 :(得分:3)

我最近致力于CRC16错误检测和单比特错误纠正。

这是基本想法:

  1. 假设您有一位错误。
  2. 如果数据+ crc没有包含错误,则CRC将为0,否则不是。
  3. 我们定义作为CRC发送的CRC和作为CRCr接收的CRC。
  4. 然后错误位由CRCox = CRCs ^ CRCr
  5. 给出
  6. 结果包括CRC错误和数据错误。
  7. 看看CRCox与误码之间的关系。
  8. 这是否清楚?我有一篇关于此的论文。如果您想了解更多,请告诉我。

答案 3 :(得分:0)

最新答案,但CRC32多项式

0x1f1922815 (= 0x787 * 0x557 * 0x465 * 0x3 * 0x3)

最多可以检测到7位错误,并且对于1024位(992位数据,32位CRC)消息,最多可以纠正3位错误。有梳(1024,1)+梳(1024,2)+梳(1024,3)= 178957824可校正的误码模式。如果有足够的内存用于1431662592字节表(178957824 * 8 =〜1.4 GB),则可以生成所有可能的1、2和3位错误CRC并将其连同索引(高32位的CRC)一起存储在该表中。位,则低32位中的3个索引,每个索引10位。

然后将对表进行排序,并且当检查CRC时,如果该表很差,则对该表进行二进制搜索(最多28个循环)可以确定是1位,2位还是3位错误情况,并使用表中存储的索引。

但是,可能会发生5个或更多位错误的错误校正。如果某些5个错误的位模式产生与3个错误的位模式相同的CRC,则错误的3位将被更改,从而导致8位的错误看上去具有有效的CRC。