奇偶校验-校验和实验
实验5-1纠错与检错
1.实验内容
读程序,在所有红色的“#”后面添加解释,说明程序的作用
2.实验题目
(1)奇偶校验码
在原始模式上增加一个附加比特位,即奇偶校验位,使最后整个模式中1的个数为奇数(奇校验)或偶数(偶校验)。
本程序用到列表、字符串合并、取模等概念。
code=input("Please input a 7-bit-binary code:")
a=0
# for 循环作用是什么
for i in range(0,6,1):
if code[i]=='1':
a=a+1
print("After odd parity checking the code is:")
if a%2==0:
print(code+'1') # 这句做了什么
else:
print(code) # 这句做了什么
print("After even parity checking the code is:")
# 下面 if .. else …作用是什么
if a%2==0:
print(code)
else:
print(code+'1')
(2) 垂直水平奇偶校验
如下图所示,14个字符纵向排列形成一个数据块,每个字符占据一列,低位比特在上,高位比特在下,用b8(第8位)作为垂直奇偶校验位,各字符的同一比特位形成一行,每一行的最右边一位作为水平奇偶校验位,这里在垂直和水平方向均采用偶校验。
# 下面的函数做了什么
def oddeven(l):
a=0
for i in range(0,len(l),1):
if l[i]=='1':
a=a+1
if a%2==0:
return '0'
else:
return '1'
block=[['0']*15,['0']*15,['0']*15,['0']*15,['0']*15,['0']*15,['0']*15,[' 0']*15]
for i in range(0,14,1):
vcode=input("Please input a 7-bit-binary code:")
for j in range(0,7,1):
block[j][i]=vcode[j]
block[7][i]=oddeven(vcode) # 这句做了什么
hcode=['0']*14
for j in range(0,8,1):
for i in range(0,14,1):
hcode[i]=block[j][i]
block[j][14]=oddeven(hcode) # 这句做了什么
print(block)
(3)循环冗余校验
任何一个二进制位串都可以用一个多项式来表示,多项式的系数只有0和1,n位长度的码C可以用下述n-1次多项式表示:
例如位串1010001可以表示为x6+x4+1。
数据后面附加上冗余码的操作可以用多项式的算术运算来表示。例如,一个k位的信息码后面附加上r位的冗余码,组成长度为n=k+r的码,它对应一个(n-1)次的多项式C(x),信息码对应一个(k-1)次的多项式K(x),冗余码对应一个(r-1)次的多项式R(x),C(x)与K(x)和R(x)之间的关系满足:
由信息码生成冗余码的过程,即由已知的K(x)求R(x)的过程,也是用多项式的算术运算来实现。其方法是:通过用一个特定的r次多项式G(x)去除x r K(x),即:
得到的r位余数作为冗余码R(x)。其中G(x)称为生成多项式(generator polynomial),是由通信的双方预先约定的。除法中使用模2减法(无借位减,相当于作异或运算)。要进行的多项式除法,只要用其相对应的系数进行除法运算即可。
本例中,10位二进制信息位串对应K(x)=x 9+x 8+ x 6+x 4+ x 3
+ x+1;CRC_4对应的G(x)=x 4+ x +1,r=4,则生成位串为10011B=19。则x r K(x)= x 13+x 12+ x 10+x 8+x 7+x 5+x 4 ,对应位串11010110110000,R(x)的计算如图 2-26所示,得出的4位余数1110作为冗余码,于是实际传输的位串为11010110111110。
参考程序:(本程序用到函数,列表、字符串合并、取整、取模等概念。) # 这个函数做了什么
def c2n(l): a=0
for i in range(0,len(l),1):
a=a+int(l[i])*(2**(len(l)-1-i)) return a
# 下面这个函数做了什么 def n2c(d): b = ''
while d!=0:
b = str(d%2)+b d = d//2 return b
informationcode=input("Please input a 10-bit-binary code:") code=informationcode+'0000' producecode=19 p=0 j=0
xorcode='' while p<14:
j=5-len(xorcode) # 下面语句做了什么
xorcode=n2c(c2n(xorcode+code[p:p+j-1])^producecode) p=p+j
print(informationcode+xorcode)
(4)校验和
校验和的算法流程如下: 发送方算法:
将待发送的数据划分成若干长度为16位的位串,每个位串看成是一个二进制数。
1 1 0 0 0 0 1 0 1 0
1 1 0 1 0 1 1 0 1 1 0 0 0 01 0 0 1 1
1 0 0 1 1 1 0 0 1 1 1 0 0 1 1
0 0 0 0 0 1 0 1 1 0
1 0 0 1 1
1 0 1 0 0 1 0 0 1 1
1 1 1 0
余数
对这些16位的二进制数进行1的补码和累加运算,累加的结果再取反作为校验和,附加到数据后面,一起发送到接收方。
上述计算中,1的补码和就是指带循环进位(end round carry)的加法,最高位有进位应循环进到最低位。
接收方算法:
将接收的数据(包括校验和)进行1的补码和累加运算,累加的结果再取反。若结果为0,表明传输正确;否则,表明传输有差错。
如图所示,在该例中,(a)是发送方的计算,①、②、③是3个数据。④是它们的1的补码和,⑤是④的反码,即校验和。发送方将⑤和数据一同发送,(b)是接收方的运算,如
(a)发送方的运算
(b)接收方的运算
由于输入的信息串是字符,要用到异或运算,而该运算只能针对数值,因此需要有将字符转换成数值,已经将数值转换成字符的相关运算,这里分别写了两个类型转换函数。
实现1的补码和的关键就是要判断最高位是否有进位,对于16进制无符号数来说,就是判断是否大于65535。
本程序只给出了发送方计算校验和的过程,用到函数、列表、字符串合并、取整、取模等概念。
def c2n(l):
a=0
for i in range(0,len(l),1):
a=a+int(l[i])*(2**(len(l)-1-i))
return a
def n2c(d):
b = ''
while d!=0:
b = str(d%2)+b
d = d//2
return b
s=0
for i in range(0,3,1):
code=input("please input a 16-bit-binary code:")
s=s+c2n(code) # 这个语句做了什么
if s>65535:
# 下面语句做了什么
s=s-65536+1
s=s^65535 # 这个语句做了什么
print(n2c(s))
(注:可编辑下载,若有不当之处,请指正,谢谢!)