【问题标题】:Error detection code for 33 bytes, detecting bit flipped in first 32 bytes33字节的错误检测码,检测前32字节翻转的位
【发布时间】:2023-03-23 00:38:01
【问题描述】:

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

Pearson 散列可以成为一种解决方案吗?

【问题讨论】:

  • 您是否需要检测单个位是否被翻转,或识别哪些位被翻转?
  • 我只需要检测发生了翻转。

标签: algorithm hash hashcode pearson error-detection


【解决方案1】:

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

现在,为了更容易理解为什么不能仅用 8 位纠错 32 字节(256 位),请阅读Hamming code(就像在 ECC 内存中使用的那样)。这种方案使用特殊的纠错奇偶校验位(以下称为“EC奇偶校验”),它只对总比特数的子集的奇偶校验进行编码。对于每个2^m - 1 总位,您需要使用m EC 位。这些代表遵循“x 位打开,x 位关闭”模式的每个可能的不同掩码,其中x 是 2 的幂。因此,一次的位数越大,您获得的数据/奇偶校验位比率就越好。例如,总共 7 个位在丢失 3 个 EC 位后只允许编码 4 个数据位,但总共 31 个位在丢失 5 个 EC 位后可以编码 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 来定位大理石:最重的盒子里装着大理石。您仅在 32、16、8、4 和 2 盒的 5 次称量中完成了任务。

同样,我们的位模式将盒子分为 5 个不同的组。向后看,第五个 EC 位确定错误是在左侧还是右侧。在我们的第 25 位场景中,它是错误的,因此我们知道错误位在组的左侧(第 16-31 位)。在我们的 EC 位 #4 的下一个掩码中(仍然向后退步),我们只考虑位 16-31,我们发现“较重”的一侧再次是左侧,因此我们缩小了位 24-31。沿着决策树向下并每次将可能的列数减半,当我们到达 EC 位 1 时,只剩下 1 个可能的位——我们的“盒子里的大理石”。

注意:这个类比很有用,但并不完美:1 位不是由弹珠表示的——错误位的位置由弹珠表示。

现在,一些人玩弄这些掩码并思考如何安排事情会发现有一个问题:如果我们尝试使所有 31 位数据位,那么我们还需要 5 个位用于 EC。但是,那么,我们如何判断 EC 位本身是否错误呢?只是一个 EC 位错误会错误地告诉我们某些数据位需要更正,我们会错误地翻转该数据位。 EC 位必须以某种方式为自己编码!解决方案是将奇偶校验位定位在数据的inside 中,从上面的位模式的列中仅设置一个位。这样,任何错误的数据位都会触发 两个 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) 一旦检测到错误,帧大小越大,必须重新传输的损坏片段的大小就越大。

【讨论】:

  • 另一种计算方式是计算需要从“接收到的数据”到“更正的数据”的映射,这样任何正确接收或只有一个位错误的数据包都将映射到原始正确数据。对于每个可能的 264 位数据包,可能有 265 种接收方式,以便能够恢复:所有位都完好无损,位 0 翻转,位 1 翻转,等等。因此,不同的数量一个可以用 264 位表示而能够恢复所有单位错误的数据包是 (2^264)/265。由于有 2^256 种组合...
  • ...256 位,并且由于 2^256 大于 (2^264)/265,这意味着要么必须存在无法表示的 256 位的某些组合,要么否则,必须有一些可表示的组合,在所有可能的单比特错误存在的情况下无法恢复。根据所存储数据的性质,其中之一可能不会造成问题。例如,如果知道原始数据的前 4 位中最多可以设置 3 位,那没有问题——那么可能只有 15*(2^252) 个可能的数据包,而且更少大于 (2^264)/265。
  • 感谢您的额外讨论。您是否发现我的信息中有任何错误?
  • 我认为这看起来是正确的,但它似乎有点压倒性。我认为计算可能的数据包的数量以及可能接收它们的方式的数量是一个简单而有用的起点。除其他外,有许多实际应用程序有一个 32 字节的数据包,但可以排除某些位组合。如果可以排除足够多的可能性,则可以仅使用 8 位补充前向纠错数据来纠正单位错误。
  • @supercat 你的意思是要么排除比特,要么通过重新编码(又名压缩)缩短长度——利用比特含义的内在知识不提供 ECC 数据对于不可能的组合。这听起来很合理。但我更感兴趣的是所有位都同等重要的一般情况。 :) 希望我的回答对你有用。
【解决方案2】:

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

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

【讨论】:

  • 对于好的多项式,请查看Koopman's CRC page0xe70x83 是大多数位长度的最佳选择,除非您知道您可以从特定位长度的更高 HD 值中受益。
【解决方案3】:

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

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

【讨论】:

  • ...虽然每 32 个字节有 9 个额外的位已经足以纠正单个位翻转!使用一位进行奇偶校验,并使用其他八位将 on 位的地址异或在一起。
  • 感谢您的回答,但您能否解释一下将“地址”异或在一起是什么意思?提前致谢。
  • @robel,例如,对于四位消息 0101,地址 1 和 3 处于打开状态,因此您可以将 01 和 11 异或一起得到 10。但事实证明,协议很简单毕竟我描述的不太好用;您需要在处理地址位时包含奇偶校验位,并且该奇偶校验位会使地址数量超过八位限制。当当。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-18
  • 1970-01-01
  • 2012-02-17
  • 2013-04-01
  • 1970-01-01
相关资源
最近更新 更多