错误检测代码为33个字节,检测位在前32个字节中翻转

时间:2011-08-25 23:48:42

标签: algorithm hash hashcode pearson error-detection

请您建议一个用于检测的错误检测方案 一个可能的位在33字节消息的前32个字节中翻转使用 不超过8位的附加数据?

Pearson哈希能成为解决方案吗?

3 个答案:

答案 0 :(得分:5)

在任何消息中检测单个位翻转只需要一个额外的位,与消息的长度无关:只需将消息中的所有位xor组合在一起,然后将其添加到最后。如果任何单个位翻转,则末尾的奇偶校验位将不匹配。

如果您要求检测哪个位翻转,则无法完成,并且一个简单的参数显示:额外的8位可以表示多达256个类的32字节消息,但零消息和256个消息,每个都有一个位,每个都必须在不同的类中。因此,有257条消息必须明确分类,只有256类。

答案 1 :(得分:2)

你可以在任何长度的消息中只用一个额外的位来检测一位翻转(如@Daniel Wagner所述)。简单地说,奇偶校验位可以指示1位的总数是奇数还是偶数。显然,如果错误的位数是偶数,那么奇偶校验位将失败,因此您无法检测到2位错误。

现在,为了更容易理解为什么你只能用8位错误纠正32字节(256位),请阅读Hamming code(就像在ECC内存中使用的那样)。这种方案使用特殊的纠错奇偶校验位(以下称为" EC奇偶校验"),其仅编码总位数的子集的奇偶校验。对于每2^m - 1个总位,您需要使用m个EC位。这些表示模式后面的每个可能的不同掩码" x位开,x位关"其中x是2的幂。因此,一次比特数越大,您获得的数据/奇偶校验比特率越高。例如,在丢失3个EC位之后,总共7位将允许仅编码4个数据位,但是在丢失5个EC位之后,总共31个位可以编码26个数据位。

现在,要真正理解这可能会举一个例子。考虑以下几组掩码。前两行将自上而下读取,表示位数("最重要的字节"我标记为MSB):

  MSB                                LSB
   |                                  |
   v                                  v
   33222222 22221111 11111100 0000000|0
   10987654 32109876 54321098 7654321|0
   -------- -------- -------- -------|-
1: 10101010 10101010 10101010 1010101|0
2: 11001100 11001100 11001100 1100110|0
3: 11110000 11110000 11110000 1111000|0
4: 11111111 00000000 11111111 0000000|0
5: 11111111 11111111 00000000 0000000|0

首先要注意的是,0到31的二进制值在从右到左的每一列中表示(读取第1行到第5行中的位)。这意味着每个垂直列彼此不同(重要部分)。由于特殊原因,我在位号0和1之间放置了一条垂直的额外行:列0没用,因为它没有设置位。

为了执行纠错,我们将针对每个EC位的预定义掩码对接收的数据位进行逐位和运算,然后将得到的奇偶校验与EC位进行比较。对于发现不匹配的任何计算奇偶校验,找到 only 这些位的列。例如,如果根据接收到的数据值计算出纠错位1,4和5是错误的,则#25列 - 仅包含那些掩码中的1 - 必须是不正确的位,可以通过翻转来纠正。如果只有一个纠错位错误,则错误在该纠错位中。这里有一个类比,以帮助理解为什么这有效:

  

有32个相同的盒子,其中一个包含大理石。您的任务是使用旧式秤(具有两个平衡平台的类型来比较不同物体的重量)来定位大理石,并且您只允许5次称重。解决方案相当简单:在秤的两侧放置16个盒子,较重的一侧指示大理石在哪一侧。丢弃较轻的一侧的16个盒子,然后称重8和8个盒子保持较重,然后4和4,然后2和2,最后通过比较最后2个盒子1到1的重量找到大理石:最重的包含大理石的盒子。您只需5次称重32,16,8,4和2箱即可完成任务。

同样,我们的位模式将这些方框划分为5个不同的组。向后,第五个EC位确定错误是在左侧还是在右侧。在我们使用位#25的情况下,它是错误的,因此我们知道错误位位于组的左侧(位16-31)。在EC位#4的下一个掩码中(仍然向后退),我们只考虑位16-31,我们发现"更重"一边是左边的一边,所以我们缩小了比特24-31。在决策树向下并且每次将可能列数减少一半之后,当我们到达EC位1时,只剩下一个可能的位 - 我们的"大理石在一个方框中"。

注意:这个类比很有用,虽然并不完美:1位不是由大理石表示的 - 错误的位位置由大理石表示。

现在,一些玩弄这些掩码并思考如何安排事情将会发现存在问题:如果我们尝试将所有31位数据位做出来,那么我们需要为EC增加5位。但是,我们如何判断EC位本身是否错误?只有一个EC位错误将错误地告诉我们某些数据位需要校正,并且我们错误地翻转该数据位。 EC位必须以某种方式编码自己!解决方案是将数据的奇偶校验位定位在内,在上面的位模式列中,只设置一位。这样,任何数据位错误都会触发两个 EC位错误,这使得如果只有一个EC位错误,我们就知道它本身是错误的而不是它表示数据位是错误。满足一位条件的列是1,2,4,8和16.从位置2开始,数据位将在这些位之间交错。(请记住,我们不使用位置0,因为它永远不会提供任何信息 - 根本不会设置我们的EC位。

最后,为整体奇偶校验添加一个比特将允许检测2比特错误并可靠地纠正1比特错误,因为我们可以将EC比特与它进行比较:如果EC比特说错了,但奇偶校验bit说不然,我们知道有2位错误,无法执行校正。我们可以使用丢弃的位#0作为我们的奇偶校验位!实际上,现在我们编码以下模式:

0: 11111111 11111111 11111111 11111111

这给我们最终总共6个错误检查和纠正(ECC)位。无限期地扩展使用不同掩模的方案如下:

32 bits - 6 ECC bits = 26 data
64 bits - 7 ECC bits = 57 data
128 bits - 8 ECC bits = 120 data
256 bits - 9 ECC bits = 247 data
512 bits - 10 ECC bits = 502 data

现在,如果我们确定我们只会得到1位错误,我们可以省去#0奇偶校验位,所以我们有以下内容:

31 bits - 5 ECC bits = 26 data
63 bits - 6 ECC bits = 57 data
127 bits - 7 ECC bits = 120 data
255 bits - 8 ECC bits = 247 data
511 bits - 9 ECC bits = 502 data

这没有变化,因为我们不再获得任何数据位。哎呀!您请求的32字节(256位)无法使用单个字节进行错误纠正,即使我们知道在最坏情况下我们只能有1位错误,并且我们知道ECC位将是正确的(允许我们将它们移出数据区域并将它们全部用于数据)。我们需要比我们多两位 - 一个必须滑到下一个512位的范围,然后省去246个数据位以获得我们的256个数据位。这样又多了一个ECC位和一个数据位(因为我们只有255位,正如Daniel告诉你的那样)。

摘要::您需要33个字节+ 1位来检测前32个字节中哪个位翻转。

注意:如果您要发送64个字节,那么您将处于32:1比率之下,因为您只需10位就可以纠错。但它在现实世界的应用程序中,"帧大小"由于以下几个原因,您的ECC无法无限期地继续上升:1)一次处理的位数可能远小于帧大小,导致严重的低效率(想想ECC RAM)。 2)能够准确地校正位的机会越来越少,因为帧越大,出错的可能性就越大,2个错误会使纠错能力失效,而3个或更多错误甚至可以打败错误 - 检测能力。 3)一旦检测到错误,帧大小越大,必须重传的损坏片段的大小越大。

答案 2 :(得分:1)

如果您需要使用整个字节而不是一点,并且您只需要检测错误,那么标准解决方案是使用cyclic redundancy check (CRC)。有几个众所周知的8位CRC可供选择。

CRC的典型快速实现使用具有256个条目的表来一次处理消息的一个字节。对于8位CRC的情况,这是Pearson算法的特例。