差错检验==编码
一。检错码==奇偶
奇偶校验是一种简单的检错技术,它通过添加一个额外的位(称为校验位)到数据块中来实现。这个额外的位用于使数据块中1的总数成为奇数或偶数,从而可以在接收端检查数据传输过程中是否发生了单比特错误。
奇偶校验类型:
- 奇校验:如果数据块中1的数量是奇数,则校验位为0;如果数据块中1的数量是偶数,则校验位为1,使得整个数据块中1的总数变为奇数。
- 偶校验:如果数据块中1的数量是偶数,则校验位为0;如果数据块中1的数量是奇数,则校验位为1,使得整个数据块中1的总数变为偶数。
工作原理:
-
发送端:
- 发送端计算数据块中1的个数。
- 根据所使用的奇偶校验规则(奇校验或偶校验),设置校验位。
- 将带有校验位的数据块发送给接收端。
-
接收端:
- 接收端收到数据块后,重新计算其中1的个数。
- 检查校验位是否符合发送时所采用的奇偶校验规则。
- 如果接收到的数据块满足原先设定的奇偶条件,则认为数据无误;如果不满足,则表明至少有一个比特位发生了错误。
示例:
假设我们使用偶校验,并且要传输的数据是8位二进制数10110010
。
-
发送端:
- 计算数据位中1的数量:
10110010
中有4个1。 - 因为是偶校验,所以校验位设为0(已有偶数个1)。
- 发送的数据为
101100100
。
- 计算数据位中1的数量:
-
接收端:
- 接收到的数据为
101100100
。 - 计算接收到的数据中1的数量:有4个1。
- 校验位为0,与偶校验规则匹配,因此接收端认为数据没有错误。
- 接收到的数据为
如果在传输过程中发生了单比特错误,比如101100100
变成了101100101
,那么接收端会发现校验位与实际接收到的数据不匹配,因为此时数据中有5个1,不满足偶校验的要求。
请注意,奇偶校验只能检测单比特错误,并不能纠正错误,也不能检测多比特错误。更复杂的错误检测方法如循环冗余校验(CRC)可以提供更高的错误检测能力。
为什么说 具有单个检验位的编码的码距为2 因此任何一位的错误都将使得码字的奇偶校验码出错?
在讨论编码方案时,“码距”(Hamming
distance)是指两个码字之间不同的位数。具有单个校验位的奇偶校验编码方案的最小码距通常为2,这意味着任意两个合法的码字之间至少有一个位不同。
为什么码距为2?
考虑一个n位的数据加上一个校验位(总共n+1位)。如果我们使用奇偶校验,那么每个合法的码字都会根据其数据位中的1的数目来确定校验位的值,以保证最终的结果是奇数(奇校验)或偶数(偶校验)。
- 对于任何合法的码字,如果改变其中一个数据位或校验位,结果将不再满足奇偶校验规则,因此得到的是非法码字。
- 如果改变两个位(无论这两个位是否包括校验位),则可能得到另一个合法的码字。但是,在这种情况下,原始码字与新码字之间的码距至少为2(因为改变了两个位)。
因此,任何单个位的改变都会导致码距为1的变化,这使得新码字不再是合法的码字,因为它们不再满足奇偶校验规则。
例子:
假设我们有一个4位数据加上1位校验位,即总共有5位的码字。我们使用偶校验:
- 数据:
1010
,校验位:0
(因为已经有偶数个1),所以码字是10100
。 - 如果第一位数据从
1
变成0
,码字变为00100
,这是非法的,因为它不再满足偶校验条件。
由于奇偶校验只能检测单比特错误,它无法区分两个比特同时发生错误的情况。例如:
- 如果第一位和第五位同时从
10100
变为00101
,虽然这是一个错误的码字,但它仍然满足偶校验条件,因此不会被检测出来。
结论:
由于奇偶校验的码距为2,单个位的错误会导致码字不再满足奇偶性要求,从而可以被检测出来。然而,如果发生多个位的错误,尤其是当错误位数为偶数时,可能会产生另一个看似合法的码字,这时奇偶校验就无法检测出这些错误了。因此,奇偶校验只适用于检测单比特错误,并且不具备纠错功能。交错检验(Interleaved
Check)是一种提高数据可靠性的技术,尤其是在需要检测和纠正多比特错误的情况下。交错检验的基本思想是通过将数据分成多个部分,并对每一部分分别应用校验位,从而增加错误检测和纠正的能力。这种方法特别适用于那些容易遭受突发错误(burst
errors)的通信环境,比如磁盘驱动器或网络传输等场景。
2.交错检验的工作原理:
-
数据分割:
- 将数据分割成多个子块或条带(stripe)。
- 每个子块独立地进行校验位的计算。
-
独立校验:
- 对每个子块独立地应用奇偶校验或其他类型的检错码(如汉明码、循环冗余校验码等)。
-
组合传输:
- 将所有子块及其对应的校验位组合在一起进行传输或存储。
-
接收端处理:
- 在接收端,数据被重新分割成相同的子块。
- 对每个子块独立地进行校验位验证。
- 如果某个子块检测到了错误,可以根据校验信息尝试纠正错误(如果是纠错码的话)。
交错检验的优点:
- 增强错误检测能力:通过将数据分散到多个子块并分别校验,可以更容易检测到突发错误。
- 提高错误纠正能力:如果使用的是能够纠错的编码方式(如汉明码),交错技术可以提高整体的错误纠正能力。
实际应用示例:
磁盘驱动器中的交错检验:
在硬盘驱动器中,交错技术经常被用来提高数据读取的可靠性。数据不是连续存储在一个长串中,而是被分割成多个较小的块,并且这些块被交错地存储在磁盘的不同位置上。这样做的好处是,即使磁盘表面存在物理缺陷,也可能只影响到一部分数据,而其他部分的数据仍然可以正确读取。
网络通信中的交错检验:
在网络通信中,特别是在无线通信环境中,交错技术可以用来对抗信道中的突发错误。通过将数据包中的数据交错分布,即使信道中出现了短时间内的高错误率,也能够通过冗余信息恢复数据。
总结:
交错检验是一种通过分割数据并对其各个部分分别进行校验的技术,可以显著提高错误检测和纠正的能力,特别是在面对突发错误时。这种方法在多种存储系统和通信协议中都有应用。
三。 奇偶校验的基本概念
奇偶校验的基本思想是在数据后面附加一个校验位,使得数据加上校验位后的1的总数达到奇数或偶数。如果接收方发现接收到的数据不符合预先约定的奇偶规则,那么就认为发生了错误。
例子
假设我们要传输一个8位的数据字10110010
,并且我们决定使用偶校验。
发送端操作:
- 计算数据位中的1的数量:
10110010
中有4个1。 - 选择校验位:因为我们需要偶校验,而数据位中已经有4个1(偶数),所以我们选择校验位为0。这样整个数据字(包括校验位)中的1的数量仍然是偶数。
- 构造完整数据字:完整的数据字变为
101100100
。
接收端操作:
- 接收数据字:接收端接收到的数据字为
101100100
。 - 计算接收到的数据字中1的数量:接收到的数据字
101100100
中有4个1。 - 验证奇偶性:
- 如果接收到的数据字中1的数量是偶数,则表示数据没有错误。
- 如果接收到的数据字中1的数量不是偶数,则表示数据有错误。
单比特错误检测示例
假设在传输过程中,第7位发生了错误,原本的101100100
变成了101100000
。
接收端操作:
- 计算接收到的数据字中1的数量:接收到的数据字
101100000
中有3个1。 - 验证奇偶性:接收到的数据字中1的数量是3(奇数),这与偶校验规则不符,因此接收端可以检测到错误。
多比特错误检测示例
假设在传输过程中,第3位和第7位同时发生了错误,原本的101100100
变成了100100000
。
接收端操作:
- 计算接收到的数据字中1的数量:接收到的数据字
100100000
中有2个1。 - 验证奇偶性:接收到的数据字中1的数量是2(偶数),这符合偶校验规则,因此接收端无法检测到错误。
总结
通过上述例子可以看出,奇偶校验可以有效地检测单比特错误,但对于多比特错误的检测能力有限。如果多个比特同时发生错误,并且这些错误导致数据位中的1的数量仍然是偶数(对于偶校验)或奇数(对于奇校验),那么奇偶校验将无法检测到这些错误。
尽管奇偶校验在某些情况下可能不足以完全保证数据的完整性,但在许多实际应用中,它仍然是一个简单有效的初步错误检测手段。对于需要更高可靠性的场合,通常会结合使用更复杂的检错码,如循环冗余校验(CRC)或汉明码等。
四。 校验和
校验和(Checksum)是一种常用的差错检测方法,广泛应用于各种通信和存储系统中。校验和的基本思想是对数据进行某种形式的计算,然后将计算结果附加到数据后面作为校验值。接收端对接收到的数据执行相同的计算,并比较计算结果与附加的校验值,以此来判断数据是否在传输过程中发生了错误。
校验和的工作原理
-
计算校验和:
- 发送端对要发送的数据进行一定的数学运算(通常是求和)。
- 得到的结果就是校验和。
-
附加校验和:
- 发送端将校验和附加到数据后面,形成完整的消息。
-
传输数据:
- 完整的消息(数据 + 校验和)被发送到接收端。
-
验证校验和:
- 接收端对收到的数据再次执行相同的数学运算。
- 将计算结果与接收到的校验和进行比较。
- 如果两者一致,则认为数据没有错误;如果不一致,则认为数据在传输过程中发生了错误。
校验和的具体实现
校验和可以通过多种方式进行计算,以下是一些常见的实现方法:
简单求和校验和(Simple Sum Checksum)
-
发送端:
- 对所有数据位求和。
- 取求和结果的模(通常取256的模,即只保留最低8位)作为校验和。
- 将校验和附加到数据后面发送。
-
接收端:
- 对接收到的所有数据位求和。
- 取求和结果的模并与接收到的校验和比较。
- 如果相同,则数据被认为正确;否则,数据被认为是错误的。
补码求和校验和(Two’s Complement Sum Checksum)
-
发送端:
- 对所有数据位求和。
- 对求和结果取二补码(先取一补码再加1)作为校验和。
- 将校验和附加到数据后面发送。
-
接收端:
- 对接收到的所有数据位求和。
- 对求和结果取二补码并与接收到的校验和比较。
- 如果相同,则数据被认为正确;否则,数据被认为是错误的。
示例
假设我们要发送的数据是一个8位的数据字10110010
,我们使用简单求和校验和方法:
发送端操作:
-
计算校验和:
- 将数据位转换为十进制:
10110010
= 178。 - 校验和 = 178 % 256 = 178。
- 将数据位转换为十进制:
-
附加校验和:
- 将校验和178(二进制为
10110010
)附加到数据后面,形成完整消息10110010 10110010
。
- 将校验和178(二进制为
接收端操作:
-
接收数据:
- 接收到的数据为
10110010 10110010
。
- 接收到的数据为
-
计算校验和:
- 将接收到的数据位转换为十进制:
10110010
+10110010
= 356。 - 取模:356 % 256 = 100(二进制为
01100100
)。
- 将接收到的数据位转换为十进制:
-
验证校验和:
- 接收到的校验和为
10110010
(十进制178)。 - 由于接收到的校验和与计算出的校验和不一致,因此认为数据在传输过程中发生了错误。
- 接收到的校验和为
总结
校验和是一种简单有效的差错检测机制,可以检测出数据传输过程中的某些类型的错误。然而,它也有局限性,例如,如果两个或多比特错误恰好相互抵消,校验和可能无法检测到这些错误。因此,在需要更高可靠性的场合,通常会采用更复杂的检错码,如循环冗余校验(CRC)或汉明码等。
成功的例子
示例场景
假设我们需要传输一组数据字,每个数据字由8位组成。我们将使用一种简单的求和校验和方法来确保数据的完整性。
数据
假设我们要传输的数据是三个8位字:10110010
、00101001
和 01010101
。
发送端操作
-
计算校验和:
- 将每个数据字转换为十进制数值:
10110010
= 17800101001
= 4101010101
= 85
- 将这些数值相加:178 + 41 + 85 = 304
- 对结果取模(通常取256的模,即只保留最低8位):304 % 256 = 48
- 将48转换回二进制:
00110000
- 将每个数据字转换为十进制数值:
-
附加校验和:
- 将校验和附加到数据后面,形成完整的消息:
10110010 00101001 01010101 00110000
- 将校验和附加到数据后面,形成完整的消息:
传输数据
- 假设数据在传输过程中没有发生任何错误,接收端接收到的数据是
10110010 00101001 01010101 00110000
。
接收端操作
-
接收数据:
- 接收到的数据为
10110010 00101001 01010101 00110000
。
- 接收到的数据为
-
计算校验和:
- 将接收到的数据字转换为十进制数值:
10110010
= 17800101001
= 4101010101
= 85
- 将这些数值相加:178 + 41 + 85 = 304
- 对结果取模:304 % 256 = 48
- 将48转换回二进制:
00110000
- 将接收到的数据字转换为十进制数值:
-
验证校验和:
- 接收到的校验和为
00110000
。 - 接收端计算出的校验和也是
00110000
。 - 由于接收到的校验和与计算出的校验和一致,因此认为数据在传输过程中没有发生错误。
- 接收到的校验和为
成功传输的例子
在这个例子中,数据在传输过程中没有发生任何错误,因此接收端能够通过校验和正确地验证数据的完整性。
总结
通过这个例子,我们可以看到,当数据在传输过程中没有发生错误时,校验和能够正确地验证数据的完整性,确保接收端接收到的数据与发送端发送的数据一致。校验和是一种简单而有效的差错检测方法,尤其适用于检测传输过程中发生的单比特错误或者少量错误。然而,需要注意的是,如果多个错误恰好相互抵消,校验和可能无法检测到这些错误。在这种情况下,更复杂的检错码(如CRC或汉明码)会更加可靠。
循环冗余校验码(重点)
循环冗余校验码(Cyclic Redundancy Check,
CRC)是一种广泛使用的检错码,它比简单的奇偶校验或校验和提供了更强的错误检测能力。CRC通过在数据后面附加一个冗余字段(校验码),使得接收端能够检测数据在传输过程中是否发生了错误。下面详细介绍CRC的工作原理、计算方法以及一个具体的例子。
CRC的工作原理
-
生成多项式:
- CRC的核心在于选择一个生成多项式(Generator Polynomial),通常用
G(x)
表示。这个多项式是一个二进制系数的多项式,长度固定,且最高位和最低位都是1。 - 选择合适的生成多项式可以优化CRC的检错能力。常见的生成多项式有CRC-8、CRC-16、CRC-32等。
- CRC的核心在于选择一个生成多项式(Generator Polynomial),通常用
-
计算冗余码:
- 发送端将数据看作一个二进制多项式
M(x)
。 - 使用
M(x)
除以生成多项式G(x)
,得到一个余数R(x)
。 - 将余数
R(x)
附加到数据后面,形成完整的发送数据T(x) = M(x) * x^r + R(x)
,其中r
是生成多项式的位数减去1。
- 发送端将数据看作一个二进制多项式
-
发送数据:
- 发送端发送包含冗余码的完整数据
T(x)
。
- 发送端发送包含冗余码的完整数据
-
接收端验证:
- 接收端收到数据后,重复同样的计算步骤,即将接收到的数据多项式除以生成多项式
G(x)
。 - 如果接收到的数据没有错误,那么余数应该为零;如果有错误,则余数不为零,表明数据传输过程中发生了错误。
- 接收端收到数据后,重复同样的计算步骤,即将接收到的数据多项式除以生成多项式
CRC的计算方法
-
二进制除法:
- CRC的计算基于二进制除法,即使用异或(XOR)运算代替减法。
- 当最高位为1时,使用生成多项式与当前数据位进行异或操作。
-
具体步骤:
- 将数据位右移
r
位(r
是生成多项式的位数减1)。 - 将生成多项式左移
r
位,与数据的最高位对齐。 - 对齐后,使用异或运算去除最高位的1。
- 继续移动并重复异或操作,直到完成所有位的处理。
- 最终得到的余数即为冗余码。
- 将数据位右移
示例
假设我们要发送的数据是11010011101100
,选择的生成多项式为G(x) = x^3 + x + 1
(二进制表示为1011
)。
发送端计算冗余码
-
数据位右移:
- 将数据
11010011101100
右移3位(因为生成多项式是4位):11010011101100 000
。
- 将数据
-
二进制除法:
- 将生成多项式
1011
左移3位,与数据的最高位对齐:11010011101100 000
。 - 进行异或运算:
11010011101100 000
XOR1011 00000000000000000
=01100011101100 000
。 - 继续异或运算,直到处理完所有的位。
- 最终得到的余数为
011
(二进制表示)。
- 将生成多项式
-
附加冗余码:
- 将余数
011
附加到数据后面,形成完整的发送数据11010011101100 011
。
- 将余数
接收端验证
-
接收数据:
- 假设接收到的数据没有发生错误,即
11010011101100 011
。
- 假设接收到的数据没有发生错误,即
-
验证冗余码:
- 将接收到的数据右移3位:
11010011101100 011
。 - 使用生成多项式
1011
进行二进制除法。 - 经过异或运算后,如果最终得到的余数为零,则表示数据没有错误。
- 将接收到的数据右移3位:
总结
通过上述例子,我们可以看到CRC如何通过生成多项式和二进制除法来计算冗余码,并且在接收端通过同样的方法来验证数据的完整性。CRC是一种非常有效且广泛应用的检错方法,能够检测大多数常见的错误模式,包括单比特错误、双比特错误以及突发错误。然而,它并不能纠正错误,只是用来检测错误的存在。对于需要纠错的应用场景,还需要结合其他更复杂的编码技术。
深入解析
在CRC计算中,将数据右移的这一步是为了创建一个足够大的空间来容纳冗余码(校验码)。这里我们详细解释一下这一步骤的目的和意义。
目的
-
创建空间:在计算冗余码之前,需要在数据后面预留足够的空间来存放冗余码。这是因为冗余码是由数据经过特定的二进制除法计算得出的余数,而这个余数的长度等于生成多项式的位数减1。
-
便于除法:将数据右移之后,可以方便地进行二进制除法运算,从而计算出冗余码。
生成多项式的选择
生成多项式(Generator Polynomial)是一个固定的多项式,通常用G(x)
表示。在这个例子中,我们选择了生成多项式G(x) = x^3 + x + 1
,它的二进制表示为1011
。因为这个多项式的位数是4位,所以冗余码(余数)的位数将是3位(生成多项式的位数减1)。
右移步骤
对于数据11010011101100
,我们需要右移3位来为冗余码预留空间。具体步骤如下:
- 原始数据:
11010011101100
- 右移3位:在数据的末尾添加3个0,得到
11010011101100 000
为什么右移3位?
因为生成多项式`G(x) = x^3 + x + 1`的位数是4位,所以冗余码的长度将是3位。我们需要在这3位中存放余数,所以在数据后面添加3个0,以确保有足够的空间来放置冗余码。
详细步骤
-
数据右移:
- 将
11010011101100
右移3位,相当于在数据的末尾添加3个0。 - 结果为
11010011101100 000
。
- 将
-
准备除法:
- 现在我们有了一个新的二进制字符串
11010011101100 000
,接下来将使用生成多项式1011
对该字符串进行二进制除法。
- 现在我们有了一个新的二进制字符串
二进制除法计算冗余码
接下来,我们使用二进制除法来计算冗余码(余数)。具体的步骤如下:
-
初始化:
- 将数据
11010011101100 000
看作多项式M(x) * x^3
,其中x^3
是因为我们右移了3位。 - 生成多项式
G(x) = x^3 + x + 1
表示为1011
。
- 将数据
-
除法过程:
- 将生成多项式
1011
左移3位,使其最高位与数据的最高位对齐。 - 使用异或运算去除最高位的1。
- 重复这个过程,直到处理完所有的位。
- 将生成多项式
具体计算如下:
- 第一次异或:
11010011101100 000
XOR1011 00000000000000000
=01100011101100 000
- 第二次异或:
01100011101100 000
XOR01011 0000000000000000
=00011011101100 000
- 重复这个过程,直到处理完所有位。
最终得到的余数(冗余码)是011
。
构造完整数据
将余数011
附加到原始数据的末尾,得到完整的发送数据11010011101100 011
。
总结
通过将数据右移3位并在末尾添加3个0,我们为冗余码预留了足够的空间,并且准备好进行二进制除法计算冗余码。这样可以确保接收端能够使用相同的生成多项式来验证数据的完整性。
补充 : 理解生成多项式
理解生成多项式(Generator Polynomial)的选择及其二进制表示非常重要,因为这直接关系到CRC的计算方法和检错能力。
生成多项式的定义
生成多项式是一个二进制系数的多项式,用于CRC的计算。多项式的系数用二进制数字表示,其中最高位和最低位必须为1。例如,多项式
G(x) = x^3 + x + 1
的二进制表示为1011
。
生成多项式的二进制表示
- 多项式的二进制表示:
- 生成多项式
G(x) = x^3 + x + 1
可以写成1 * x^3 + 0 * x^2 + 1 * x + 1
。 - 这意味着最高次项的系数为1,接下来的系数依次为0、1、1。
- 因此,该多项式的二进制表示为
1011
。
- 生成多项式
为什么选择G(x) = x^3 + x + 1
?
-
多项式的位数:
- 生成多项式的位数决定了冗余码的长度。在这个例子中,
G(x) = x^3 + x + 1
是一个4位的多项式(最高次项为x^3
),因此冗余码的长度为3位(生成多项式的位数减1)。
- 生成多项式的位数决定了冗余码的长度。在这个例子中,
-
检错能力:
- 不同的生成多项式有不同的检错能力。选择合适的生成多项式可以优化CRC的检错性能。
G(x) = x^3 + x + 1
是一个常用的生成多项式,它可以检测到以下类型的错误:- 所有的单比特错误。
- 所有的双比特错误(如果生成多项式的位数大于2)。
- 所有奇数长度的突发错误(burst errors)。
-
标准和实践:
- 在实际应用中,有许多标准的生成多项式被广泛使用,如CRC-8、CRC-16、CRC-32等。这些多项式已经经过了大量的测试和验证,证明了它们的有效性和可靠性。
- 选择
G(x) = x^3 + x + 1
是为了简化示例,并且展示了基本的CRC计算方法。在实际应用中,可能会选择更复杂的多项式以获得更好的检错效果。
生成多项式的特性
-
多项式的不可约性:
- 不可约多项式(Irreducible Polynomial)通常用于生成多项式,因为它们具有良好的数学性质,可以提供更好的检错能力。
G(x) = x^3 + x + 1
是一个不可约多项式。
-
多项式的位数选择:
- 位数的选择取决于所需的检错能力和冗余码的长度。位数越大,冗余码就越长,检错能力就越强,但同时也增加了计算的复杂度。
示例总结
在我们的示例中,选择了生成多项式G(x) = x^3 + x + 1
,其二进制表示为1011
。这个多项式决定了冗余码的长度为3位,并且具有一定的检错能力,可以检测单比特错误和奇数长度的突发错误。
计算冗余码的过程
为了计算冗余码,我们按照以下步骤进行:
-
将数据右移:
- 将数据
11010011101100
右移3位,并在末尾添加3个0,得到11010011101100 000
。
- 将数据
-
二进制除法:
- 使用生成多项式
1011
对扩展后的数据进行二进制除法,计算出余数。
- 使用生成多项式
-
附加冗余码:
- 将计算出的余数附加到原始数据的末尾,形成完整的发送数据。
通过这种方式,接收端可以使用相同的生成多项式来验证数据的完整性。