可用于SDR的C语言纠错编码通用算法收集(1)-朴素字典查表BCH纠错
在开设了SDR软件无线电课程后,有余力的学生开始尝试开发自己的小通信电台,实现Hello World的无线传输。在实验过程中,一定会遇到纠错的问题。即使是在实验室,理想化的信道也是不存在的。没有纠错的小电台,稍微离开一两米就会发生传输错误。
在通信专业的实验课程里,通常只采用matlab等类似的高级语言进行原理性的测试。但此类高级语言过于顶层,使得学生无法了解算法内部究竟做了什么。此外,基于GUNRadio现有的纠错模块,基本是使用几类固定的编译码类型,且封装的很深。
为了配合学生借助 taskbus进行纯控制台STDIO模块的开发,我们收集了手头的通用纠错算法,便于学生进行开发学习。这里把资源中比较特殊的几个算法介绍一下,准备陆续写几篇短文。
1. 循环冗余纠错的能力极限
这类编码典型包括CRC, BCH等编码。当然,一般认为CRC是没有纠错能力的。但是,当参与校验的信息很少时,CRC就具备了不完备的纠错能力。定性的看,考虑一个多项式构造的校验结构有无纠错能力,就看两个方面:
- 纠错比特数能表达多少种错误类型。
- 多项式能不能保证图案的唯一性(纪念伟大的数学家伽罗华,建立了近世代数,奠定了图案唯一性的理论基础)。
比如,如果整体码长为N,校验位数为m,则如果 N<2mN < 2^mN<2m则有可能纠出1位错误。前提是采用的多项式是本原的(可类比素数)。在校验位数=4时,码长N必须小于16。因为4比特总共只能表达15种非0图案。类推下去,设最大可纠错的个数是e,则当
∑i=1eCni<2m\sum_{i=1}^{e} C_n^{i} <2^mi=1∑eCni<2m
时,有望纠出e位以内的错误。这种理解相当于模拟出错的过程,假设错1位,则从n个位置取出1个位置进行翻转,共有Cn1C_n^1Cn1=n种可能。假设错2位,则从n个位置取出2个进行翻转,共有Cn2=n(n−1)/2C_n^2=n(n-1)/2Cn2=n(n−1)/2种可能,以此类推。校验的位数要能区分所有的错误图案,因此存在一个最小值,也就是∑i=1eCni\sum_{i=1}^{e} C_n^{i}∑i=1eCni
同时,由于模二计算具备一定的性质,使得错误的图案(出现错误的位置)和校验的结果形成映射,因此在接收方只要通过比对结果,就可知道错误的位置。
2. 字典纠错算法
在计算机不发达的时代,科学家主要研究的是设计一种编码方法,可以通过余数直接求取错误图案。最著名的BCH编码、RS编码,不是单纯因为纠错能力强,而是在于有标准的逆推算法,可以在有限的存储和时间下完成纠错。字典方法在那个时代也是存在的,因为它是最朴素的算法。但是受制于只有1MB内存的286机器,该算法没有实用价值。
2.1 步骤
对当前动辄16GB的内存存储容量而言,借助现代通用计算机的大容量内存,可以轻松实现最为朴素的字典纠错。算法步骤:
- 确定基本参数,总长度(被除数长度)、校验多项式长度(除数)。假设出错个数e初始化=1
- 做CneC_n^{e}Cne穷尽,用到了排列组合工具库简化过程。对每个错误位置,执行3-5步。
- 产生错误图案。
- 计算校验结果,求取余数。
- 记录图案:错误位置映射,如果发现重复图案或者字典过大,则结束(到7)。
- e=e+1,转2继续。
- 保存字典。
2. 2 局限与优势
主要的局限在于产生字典的过程较长。但字典的产生是一次性的,一次产生,多次使用。一旦字典生成,查表的过程很快。
3. 调用例子
int demo_bch()
{using namespace RC_DICTCODEC;using std::vector;using std::string;//0. 定义编码多项式size_t pins[7] = {10,8,5,4,2,1,0};rc_codec_bch codec(15,5,pins,7);rc_dict<char> dict;//1. 构造字典size_t s = dict.init(&codec);printf ("Dict size = %u\n",s);//2. 提供信息,共5比特,11001char code[15] = {1,1,0,0,1,0,0,0,0,0,0,0,0,0,0};//3. 编码codec.encode(code,code);//4. 模拟传输错误code[3] = 1-code[3];code[7] = 1-code[7];//5. 执行校验char check[15] = {0};codec.chcode(code,check);//6. 查表纠错string errk = codec.hash(check);vector<rc_dict<char>::err_mask > err = dict.err_find( errk);for (size_t i=0;i<err.size();++i){printf("Pos = %d, Add = %d\n",err[i].index,err[i].err);if (err[i].index>=0 && err[i].index<15)code[err[i].index] = codec.mod_m_add(code[err[i].index],err[i].err);}//输出,判断余数是不是0codec.chcode(code,check);printf ("chk code=");for (int i=0;i<15;++i)printf("%d",check[i]);printf ("\n");return 0;
}
4. C语言封装
由于C++语言对其他语言包括python,C#不友好,我们参考这篇文章的方法,提供一个非常通用的C语言接口。
/*** @brief oc_bch_new_codec 分配一个BCH码编译码器* @param n 整个编码后的块长度* @param k 信息长度* @param gindex 非零多项式位置,如10,9,8,6,0* @param len 位置项个数,如 5 个(上面的例子)* @param dict_size 字典大小(条)* @return BCH纠错码编译码器句柄*/
void * oc_bch_new_codec(size_t n, size_t k, const size_t gindex[], size_t len, int dict_size);/*** @brief oc_bch_delete_codec 释放BCH码编译码器 codec* @param codec BCH码编译码器*/
void oc_bch_delete_codec(void * codec);/*** @brief oc_bch_initcodec 首次使用前,要创建字典进行初始化。* @param codec BCH纠错码编译码器* @param status 指定余数初态(默认是全0)* @param bigendian gindex的大小端。* @return*/
int oc_bch_initcodec(void * codec,const char status[/*n-k*/],int bigendian);/*** @brief oc_bch_encode 对字节型的信息data进行纠错编码,存储到code中。* @param codec BCH纠错码编译码器* @param data 信息data* @param code 编码code* @return 0表示成功*/
int oc_bch_encode(void * codec,const char data[/*k*/], char code[/*n*/]) ;/*** @brief oc_bch_decode 对字节型的数据code进行纠错译码* @param codec BCH纠错码编译码器* @param code 待纠错的数据* @param result 纠错后的数据存储到result中* @param checkedCode 可选择对result进行校验,输出到checkedCode里。可以传入nullptr* @return*/
int oc_bch_decode(void * codec,const char code[/*n*/], char result[/*n*/], char * checkedCode) ;
5. GUI测试界面
如果有Qt,则可以编译并使用ocgui测试:
可以发现,经过纠错后,图片可以被正确打开。
6. 代码链接
相关代码参考
https://gitcode.net/coloreaglestdio/open_codec
可用于SDR的C语言纠错编码通用算法收集(1)-朴素字典查表BCH纠错相关推荐
- 可用于SDR的C语言纠错编码通用算法收集(3)-卷积码与Viterbi译码
为了配合学生借助 taskbus进行纯控制台STDIO模块的开发,我们收集了手头的通用纠错算法,便于学生进行开发学习.今天介绍卷积码以及维特比译码算法.在我自己以前学习<通信原理>的时候, ...
- 可用于SDR的C语言纠错编码通用算法收集(4)-LDPC低密度奇偶校验码
为了配合学生借助 taskbus进行纯控制台STDIO模块的开发,我们收集了手头的通用纠错算法,便于学生进行开发学习.今天介绍LDPC编码. 1. 低密度奇偶校验编码LDPC 低密度奇偶校验码LDPC ...
- 算法训练+乘法表c语言,[蓝桥杯][算法提高VIP]输出九九乘法表 (C语言代码)
解题思路:Nine那些直接复制输出 注意事项: 参考代码: #include int main() { int i,j; printf(" Nine-by-nine Multiplicat ...
- c语言如何热敏电阻转成温度,NTC热敏电阻查表程序如何转换成温度显示?
昨天弄一整天,把数据表更新下,测试发现在用烙铁靠近NTC时,温度最高只有70多度就上不去了,测了NTC输入电压是有变化的,但显示基本没什么变化,将上偏电阻原5.1K改为2.4K后,还是这样子.不知是那 ...
- 一步一步写算法(之通用算法的编写)
[ 声明:版权所有,欢迎转载,请勿用于商业用途. 联系信箱:feixiaoxing @163.com] 前面我们写过各种各样的算法,什么排序.查找.二叉树.队列.堆栈等等.但是我们在编写这些代码的时 ...
- c语言系统的通用数据结构,(转载)C语言实现通用数据结构的高效设计
(转载)C语言实现通用数据结构的高效设计 [复制链接] 使用宏替代模板的方案 最近在阅读一个开源的C++代码,里面用到了大量的STL里面的东西.也许是自己一直用C而很少用C++来实现算法的原因,STL ...
- 基于 Ruby 谈谈——程序设计语言的通用框架
基于 Ruby GScript 谈谈--程序设计语言的通用框架 目录 基于 Ruby GScript 谈谈--程序设计语言的通用框架 一.架构思维导图 1.Ruby GScript 介绍 2.实践: ...
- ICCV 2021| GRF: 用于三维表征和渲染的通用神经辐射场(已开源)
作者丨Bo Yang@知乎 来源丨https://zhuanlan.zhihu.com/p/399867075 编辑丨3D视觉工坊 论文链接: https://arxiv.org/abs/2010.0 ...
- C语言实现通用链表初步(一)
注意:本文讨论的是无头单向非循环链表. 假设不采用Linux内核链表的思路,怎样用C语言实现通用链表呢? 一种常用的做法是: typedef int element_t; struct node_in ...
最新文章
- go语言的defer语句
- linux 搭建Tomcat
- 基于hexo搭建个人免费博客——基本设置和了解
- EIGRP Metric计算
- PAT (Advanced Level) 1140~1143:1140模拟 1141模拟 1142暴力 1143 BST+LCA
- LeetCode 74. 搜索二维矩阵(二分查找)
- 云函数查询_速览 | 京东云5月重要产品与功能更新
- Dataguard学习笔记
- AMD因虚假宣传遭集体诉讼 向消费者赔偿1210万美元
- AI助特朗普当选?FB史上最大数据滥用曝光,牵出ACL终身奖得主
- Python学习入门基础教程(learning Python)--5.7 Python文件数据记录存储与处理
- python编程例子-python网络编程实例简析
- mysql常见字符串处理函数
- Python + vs +Opencv
- 苹果6s上市时间_苹果6s主板坏了的症状,苹果6s换主板多少钱
- 第5章 软件质量标准概述
- 精易论坛多线程培训第二期
- 4. 查询表orders——检索所有订单订购物品的总数
- 六轴机械臂下位机(arduino)+上位机(ROS+Moveit)---(一)机械臂硬件
- 用计算机唱歌弹奏china,新目标英语专题练习:句型转换(附答案)
热门文章
- 使用canvas对图片进行裁切
- mysql 实例和数据库名_oracle 实例名和服务名以及数据库名区别
- Win10隐藏状态栏图标的方法
- 解决windows 2003 sp1下安装arcsde 9.0 for sql server 2000 sp4概要方案
- 第四章、面向对象(2)
- 英语表达的收集类游戏
- python画图颜色填充_【Python】Matplotlib画图(十一)——箱线图
- 分享一款好用的微信相册小程序《群相册大师》
- 计算机怎么一键返回桌面,回到桌面的快捷键是啥_快速桌面快捷键怎么操作-win7之家...
- 华为智慧办公全系列终端介绍