本文中的py代码采用了numpy库 方便进行计算。
文章背景:学了通信原理的差错控制编码后,想要尝试以下利用py进行仿真
这也是我第一次使用py的numpy库 不合理的地方欢迎指出

文章目录

  • 1.普通奇偶校验
    • 1.1 基础理论
    • 1.2 代码实现
  • 2.纵向奇偶校验
    • 2.1 基础理论
    • 2.2 代码实现
  • 3.水平奇偶校验
    • 3.1 基础理论
    • 3.2 代码实现
  • 4.循环冗余码
    • 4.1 基础理论
    • 4.2 代码实现

1.普通奇偶校验

1.1 基础理论

是一种通过检查消息序列中1的奇偶数的校验方法

例如1011中,1的个数是奇数。如果我们进行的是偶校验 那么就要在结尾补上1,使数列变为 10111,如果是1001这种1的个数是偶数的,进行偶校验就是直接添0,变成10010。

发送方和接收方约定好奇校验还是偶校验,对应的编码解码就可以了。

缺点在于 无法检测偶数个错误,因为偶数个错误会让取余都不满足

本质原因是因为校验位只有一位,消息序列也只有一个维度(后面会解释为什么要用一个维度这个词),下两个奇偶校验方法会通过增加维度来解决。

1.2 代码实现

编码端

# 生成基础奇偶校验码
def base_parity_code(is_sigular,size):row_code =  np.random.randint(0,2,size-1)result = np.sum(row_code)if result%2 == is_sigular: #传0就为偶校验,因为偶数对2取余为0 矩阵添0row_code = np.append(row_code,[0])else:row_code = np.append(row_code,[1])return row_code
row_code = base_parity_code(0,8) #随机生成八位的信息序列 含一位校验
print(row_code) #[0 1 0 0 0 0 1 0]

解码端

#接收端校验
def base_parity_check(r_code,is_sigular):result = np.sum(row_code)if result%2 == is_sigular:#奇数print('校验成功')else:print('校验失败')

模仿传输中出现的错误直接改变消息序列的位就行了。

2.纵向奇偶校验

2.1 基础理论

看了前面最普通的奇偶校验的缺点,该如何在基于奇偶基础上进行改进呢?这里用到了线性代数的思想。

普通奇偶校验因为只对有一行进行校验,那么显然校验码所能做到的就只有 监视该行的奇数个错误了,试想以下,如果我们增加校验位,校验多个行(或者多个列)不就可以校验出部分的偶数个错误了?

举个例子

[1,0,0,1,0]  就只能校验奇数个错误比如如果前两个码元错误 变成了[0,1,0,1,0]是监视不出来的
那如果我们将其变为这种形式
a = [1,0,0,1,1,1] 那么a[1]和a[0]由a[4]监视,a[2]和a[3]由a[5]监视。
此时我们相当于多了一个监视行(列)数 我们写成矩阵的形式较为方便理解
a = [[1,0],   #前面的a[0]a[1][0,1]      #前面的a[2]a[3][1,1]]   #前面的a[4]a[5]
这里我是以列的形式构造,每列的最后一个就是监督位。
此时如果 又发生了偶数个,例如a[1]a[0]的错误,那么很容易就可以发现了
很明显每列不再是偶数个1了,这样就不是之前那种只能检测奇数个错误的情况了
当然,如果偶数个错误发生在同个列上,还是无法检错
a = [[0,1],   #假设这第一行横起来的两位错误就可以检错[0,1]      #如果是竖起来的两位错了就不行了[1,1]]

2.2 代码实现

is_signal = 0
err_flag = 0#编码
raw_code = np.random.randint(0,2,[4,8]) #随机生成4行8列的矩阵 传输32位码元
print('生成序列\n',raw_code)
temp_arr = np.zeros(raw_code.shape[1],dtype=np.int32)#生成一个监督码组,长度为码元矩阵的列数
for i in range(raw_code.shape[1]):#对每列进行奇偶校验编码,并将码值放在数组里result = np.sum(raw_code[:,i])if result%2 == is_signal:temp_arr[i] = 0;else:temp_arr[i] = 1;
raw_code = np.r_[raw_code,[temp_arr]]#将监督码组追加到最后一行中
print('编码后序列\n',raw_code)
#生成序列
# [[1 0 0 1 0 1 0 0]
# [0 0 1 0 1 0 0 0]
# [1 1 0 0 0 0 1 0]]
#编码后序列
# [[1 0 0 1 0 1 0 0]
# [0 0 1 0 1 0 0 0]
# [1 1 0 0 0 0 1 0]
# [0 1 1 1 1 1 1 0]]
#解码
err_flag = 0
for i in range(raw_code.shape[1]): #对每一列 进行奇偶校验result = np.sum(raw_code[:,i])if result%2 != is_signal:err_flag = 1
if err_flag:print('检测到错误')print('错误序列为')print(raw_code)
else:print('检测不到错误')

3.水平奇偶校验

3.1 基础理论

利用上述的编码其实已经能实现效果不错的检错了,但是这种编码,很多多位的,偶数个的错误也能被成功检测出来,但是有一类错误还是无法被检查出来, 那就是只有每一列的错误都是刚好偶数个时无法检错了因为本质上 可以理解为,我们只是做了个多列的奇偶校验

解决思路很简单, 将行也加入我们的监督码组中,对每一列,每一行 都进行奇偶校验 将监视的维度升维(线性代数的思想真的牛啊)

从只对一列的单点进行检测
改为对多列连成的线进行检测
最后变为多行多列形成的面进行检测

3.2 代码实现

is_signal = 0
err_flag = 0#编码
raw_code = np.random.randint(0,2,[4,8])
print('生成序列\n',raw_code)
temp_arr = np.zeros(raw_code.shape[1],dtype=np.int32)
for i in range(raw_code.shape[1]): #生成每一列的监督码result = np.sum(raw_code[:,i])if result%2 == is_signal:temp_arr[i] = 0;else:temp_arr[i] = 1;
raw_code = np.r_[raw_code,[temp_arr]]
print('垂直编码后序列\n',raw_code)temp_arr.resize(raw_code.shape[0]);#将矩阵大小重新指定
for i in range(raw_code.shape[0]): #生成每一行的监督码result = np.sum(raw_code[i,:])if result%2 == is_signal:temp_arr[i] = 0;else:temp_arr[i] = 1;
raw_code = np.c_[raw_code,temp_arr.T]#因为是行监督组 是竖起来的 所以放了矩阵的转置
print('水平编码后序列\n',raw_code)
#生成序列
# [[0 1 1 0 1 1 1 0]
# [1 0 1 1 1 0 0 0]
# [1 0 0 1 1 1 1 1]
# [1 1 0 0 0 0 1 0]]
#垂直编码后序列
# [[0 1 1 0 1 1 1 0]
# [1 0 1 1 1 0 0 0]
# [1 0 0 1 1 1 1 1]
# [1 1 0 0 0 0 1 0]
# [1 0 0 0 1 0 1 1]]
#水平编码后序列
# [[0 1 1 0 1 1 1 0 1]
# [1 0 1 1 1 0 0 0 0]
# [1 0 0 1 1 1 1 1 0]
# [1 1 0 0 0 0 1 0 1]
# [1 0 0 0 1 0 1 1 0]]
#解码
err_flag = 0
for i in range(raw_code.shape[1]):#对列进行校验result = np.sum(raw_code[:,i])if result%2 != is_signal:err_flag = 1for i in range(raw_code.shape[0]):#对行进行校验result = np.sum(raw_code[i,:])if result%2 != is_signal:err_flag = 1if err_flag:print('检测到错误')
else:print('检测不到错误')

这样的话,如果是之前那种竖起来的偶数个错误,也会被检测到了,因为竖起来的在列上看不出来,可是在行上确是错误的了.

但是还是有一种极端情况,那就是列中的偶数个错误的两个位置,在另外一个列的相同两个位置也错误了 那这个时候就相当于当该列上错误x个的时候,列监督位检查不出来,同时除了此列,还存在奇数个不同列但同行的位置也错了x个.就无法查错了 (x为偶数)

举例子这样子就无法检错了

raw_code[0,0] = not raw_code[0,0]
raw_code[1,0] = not raw_code[1,0]
raw_code[0,1] = not raw_code[0,1]
raw_code[1,1] = not raw_code[1,1]

不得不说 突然发现线性代数的一些思想真的好奇特

4.循环冗余码

4.1 基础理论

这方面其实csdn有特别多的优秀教程了。

总的来说就是双方约定一个多项式 发送方利用自己和该多项式相除得到一个余数,把余数添加到自己的末尾。

接收方就是拿着这个信息再去和多项式相除,此时信息末尾已经添加上余数了。所以除法的结果如果为0,那么就是正确接收

4.2 代码实现

raw_code = np.random.randint(0,2,16)#产生16位随机序列
print('原始数据是       :',raw_code)
#多项式X8+X5+X4+X0 这是专家们研究的CRC8的 其他的也不是不行
gx = np.array([1,0,0,1,1,0,0,0,1]) #产生一个最高次方为len(gx)的矩阵 后面转化为多项式
print(np.poly1d(gx))
print('除数(生成多项式) :',gx)
raw_code = np.r_[raw_code,np.zeros(len(gx)-1)].astype(np.int32) #在原序列后添加len(gx) - 1个0
print('被除数           :',raw_code)
temp_result = (np.poly1d(raw_code)/np.poly1d(gx))[1]#将生成多项式和原序列进行多项式除法取余数
temp_result = np.mod(temp_result,2).astype(np.int32)#对余数进行模2得到校验位
print('校验位           :',temp_result)
for i in range (len(temp_result)):#用余数替换掉刚刚补0的位置index = len(raw_code) - len(temp_result)raw_code[index+i] = temp_result[i]
print('编码序列         :',raw_code)
#原始数据是        : [0 0 0 0 0 0 1 0 1 1 1 0 0 0 1 1]
#除数(生成多项式)   : [1 0 0 1 1 0 0 0 1]
#被除数            : [0 0 0 0 0 0 1 0 1 1 1 0 0 0 1 1 0 0 0 0 0 0 0 0]
#校验位            : [1 0 0 1 0 1 1]
#编码序列          : [0 0 0 0 0 0 1 0 1 1 1 0 0 0 1 1 0 1 0 0 1 0 1 1]
#再次对多项式进行除法 此时余数为0就是校验成功否则校验失败
result = (np.poly1d(raw_code)/np.poly1d(gx))[1];
result = np.mod(result,2).astype(np.int32)
print(result)
print(np.all(result==0))

三类奇偶校验码及循环冗余码相关推荐

  1. 【计算机网络】数据链路层 : 差错控制 ( 检错编码 | 奇偶校验码 | CRC 循环冗余码 )★

    文章目录 一. 奇偶校验码 二. 奇偶校验码 特点 三. 奇偶校验码 示例 四. CRC 循环冗余码 ( 原理说明 ) 五. CRC 循环冗余码 计算示例 六. CRC 循环冗余码 生成多项式 一. ...

  2. 数据链路层 功能 封装成帧 透明传输 字符计数法 字符填充法 零比特填充法 违规编码法 传输中的差错 差错控制 冗余编码 奇偶校验码 CRC循环冗余码 检错过程 细解 图解 通俗易懂

    粉丝不过W 数据链路层: 结点:主机.路由器 链路:网络中两个结点之间的物理通道,链路的传输介质:双绞线.光纤和微波,分为有线链路.无线链路 数据链路:网络中两个结点之间的逻辑通道,把实现控制数据传输 ...

  3. 数据链路层差错控制——奇偶校验码、循环冗余码和汉明码(海明码)

    差错控制 传输中的差错由噪声引起.一类称为热噪声,是信道所固有的.持续的,并且随机的.另一类是外界环境造成的短暂的冲击噪声.热噪声可以通过提升信噪比降低干扰.而后者不可以通过提升信号幅度来避免干扰,带 ...

  4. 3.3.1网络原理数据链路层之差错控制(检错编码和纠错编码)-(奇偶校验码、CRC循环冗余码、海明码)

    文章目录 0.脑图时刻 1.为什么会出现差错? 2.检验和纠正差错的编码方法 (1)关于数据链路层和物理层的编码区别 (2)冗余编码 3.检错编码 (1)奇偶校验码 (2)循环冗余码(CRC) 4.纠 ...

  5. 3.3.1网络原理数据链路层之差错控制(检错编码和纠错编码)->(奇偶校验码、CRC循环冗余码、海明码)(转载)

    原文链接:https://blog.csdn.net/weixin_43914604/article/details/104864783 本博客为个人学习.研究或者欣赏用,如有侵权,请与我联系删除,谢 ...

  6. 数据链路层之差错控制(检错编码和纠错编码)-(奇偶校验码、CRC循环冗余码、海明码)...

    思维导图 为什么会出现差错? 检验和纠正差错的编码方法 关于数据链路层和物理层的编码区别 冗余编码 检错编码 关于检验码和纠错码中的奇偶校验码.循环冗余码(CRC).海明码可参考我之前写的:校验码(一 ...

  7. 计算机网络 - 数据链路层

    一. 数据链路层的功能 数据链路层在物理层提供服务的基础上向网络层提供服务,其主要作用是加强物理层传输原始比特流的功能,将物理层提供的可能出错的物理连接改造为逻辑上无差错的数据链路,使之对网络层表现为 ...

  8. 【考研408】计算机网络笔记

    文章目录 计算机网络体系结构 计算机网络概述 计算机网络的组成 计算机网络的功能 计算机网络的分类 计算机网络的性能指标 课后习题 计算机网络体系结构与参考模型 计算机网络协议.接口.服务的概念 IS ...

  9. 计算机网络(考研知识梳理)

    计算机网络(考研知识梳理) 数据链路层(二) 1.数据链路层的功能 2.组帧 3.差错控制 4.流量控制与可靠传输机制 5.介质访问控制(MAC) 6.局域网 7.广域网 8.数据链路层设备 一. 数 ...

最新文章

  1. 重庆市档案局(馆)数据备份一体机项目
  2. 【Unity】6.1 Unity中的C#脚本基础知识
  3. Orleans稍微复杂的例子—互动
  4. 审查指南 最新版本_代码审查-最终指南
  5. Hamcrest匹配器常用方法总结
  6. jQuery源码解读二(apply和call)
  7. WeX5 - AJAX跨域调用相关知识-CORS和JSONP
  8. [境内法规]中国人民银行关于印发《反洗钱现场检查管理办法(试行)》的通知—银发〔2007〕175号
  9. Android 自定义和可下载字体
  10. struct termios结构体详解【转】
  11. radam+lookahead optimizer
  12. ad转3d视图快捷键_【技术干货】PCB工程师不得不看:超级实用AD常用快捷键总结...
  13. 作为一名优秀的程序员,如何选购适合自己的显示器
  14. 函数凹凸性证明中点函数值和函数值中点的关系
  15. android insert方法,史上最精炼android四大组件基础总结(忘记了的可以过一遍)
  16. robot_localization中EKF源码介绍
  17. Unity常用插件免费下载 2018.9.4持续更新
  18. Kaggle比赛----入门指导
  19. .nii格式文件python_python处理nii格式文件
  20. JavaWeb详解加实战

热门文章

  1. 室内定位技术:UWB、蓝牙、RFID和WIFI——谁将是主角
  2. SAP 深入理解库存
  3. linux中如何复制文件并重命名_linux 下文件重命名/移动/复制命令(转)
  4. 维修电工电气控制及仪表照明实训装置
  5. 爬虫百战穿山甲(总部)
  6. LRP\PMC\BRP 计划系统 简介
  7. fcn从头开始_如何从头开始构建基本的聊天机器人
  8. 不知道看了之后会有啥感想,雪铁龙富康二手车置换的故事,能吸引人最好啊
  9. 工厂模式下的动态Mybatis-Plus
  10. SSL证书类型DV SSL、OV SSL和EV SSL区别选择方法