纠错码简介

纠错码是个什么东西

引出

网络中的通信基于TCPUDP两个通信协议, 这大家都知道的, 什么TCP的三次握手等等, 面试经常被问到. 三次握手是为了保证连接的正确建立. 但是, 在通信的时候, 你如何保证你的消息正确送达了呢? 有人说了, 有收到请求的响应包. 但我说的不是这个,

比如说, 你发送了一个数字1, 你如何保证接受方收到的数字也是1呢? 毕竟, 在网络中环境如此复杂, 就算是物理上也不能保证数据一定是不变的啊. 比如有一个机房在上海, 你在北京访问, 那数据是要途径一千多公里的, 在这个传输的过程中会受到各种干扰, 很难保证数据不会失真.

这个时候, 纠错码出现了. 简单介绍一下, 其中所有有关数学的内容的去掉了, 毕竟太高深, 咱也不懂.

思考

因为计算机传输中只存在0和1, 所以可以简单将其类比为数字.

想象一个场景, 你需要将一组数字发送给B, 在发送的过程中, 每个数字都有20%的概率变成其他数字(途中收到干扰导致失真). 你们应该如何保证接收到的数字与发送的数字一致呢?

假定这组数字是: 123456789

方案一

根据概率论, 每个数字20%的概率会错乱, 也就是有80%是正确的. 那只要样本足够多, 那出现次数最多的就是正确的.

比如, 发送了5次, 收到的内容是:

  • 123456781
  • 127456789
  • 623456789
  • 123456789
  • 123459789

将每一位单独拿出来, 找到出现次数最多的数字就是正确的数字.

但是, 这样不能保证完全正确, 毕竟是概率事件, 需要通过增大样本数量来增加准确率. 只要传输的次数足够多, 就能够将错误的概率降低到足够小.

很好, 这样确实能解决问题. 但是, 如果只是通信间传输几k的数据还好, 如果下载一个1G的电影, 为了纠错, 需要你耗费10G的流量下载10遍, 你能接受么?

方案二

方案一被pass了. 既然多次传输不行, 又该如何是好呢? 单次传输的话, 仅仅依靠消息本身是肯定无法保证可靠的.

换个角度想一下, 既然每个数字的出错概率是20%, 那么如果将1个数字映射到4个数字上面, 整体出错的概率就下降了. 为了方便理解, 使用英文来表示映射关系, 即1(one), 2(two)...

如果你收到了一个数字345, 告诉你其中可能存在错误, 你是无法知道它原本的数字是什么的. 但如果你收到的是 ofe, 你应该能够很快想到它是 one, 并将其还原.

这个时候, 假设你收到的数据是这样的: one tno shree four fiae . 你应该能够很快将其还原为: 12345 . 只需要检查每个单词, 若是有效的直接转换, 若是无效的则转换为最接近的单词.

当然, 计算机在传输过程中是无法传输英文的, 所以将数字映射到另一个较长的数字(编码)上去. 这个编码就是 汉明代码. 如下:

  • 0000 -> 0000000
  • 0001 -> 0001011
  • 0010 -> 0010111
  • ...

将每一个4位都转换为7位. 这种方案存在匹配后的值是一个较接近的错误的值么? 据说不会, 涉及到数学领域, 没太懂.

至此, 其实纠错的任务已经接近完成了. 通过数据的冗余, 已经可以将出错的概率降低到很小了.

方案三

能否使用更少的数据来进行纠错呢? 下面介绍的就是了, 一种称为校验和的手段. 这种方法仅仅用来校验数据是否出错, 但不会对数据进行修复.

比如你需要传输的数字是: 4567.

在后边添加一位数字作为校验数字, 校验数字的生成规则是四个数字的和取个位数. 即: 4+5+6+7=22, 校验数字为 2.

当接到45672 这个数字时, 只需要进行简单的计算, 就可以知道数据是否正确. 其中任何一个数字出错, 结果都不会是2. 但是, 如果有两个数字出错呢? 你收到的数字是: 44772. 你通过计算发现校验数字是2. 嘿嘿.

也就是说, 一个校验数字只能保证一位出错的情况, 这时通过添加校验数字, 通过另外一个生成规则再生成一个校验数字添加到后边(这里不能使用同一个生成规则), 就可以处理两位出错的情况了. 但是三位出错呢? 为了保证完全校验, 就需要添加更多位数的校验数字.

但是如果是一个100mb的文件, 总不能用于校验的大小也是100mb吧. 勿慌, 只需要一个100位的数字进行校验. 这里又涉及数学领域了, 其出错的概率微乎其微, 几乎可以忽略.

还记得在各个官网下载文件的时候附送的MD5校验码吗? 没错, 就是它了. 可以校验文件在传输过程中是否被损坏或是否被篡改.

方案四

上面是添加校验数字的方案只能够检测数据是否出错, 而不能够对出错的数据进行修复. 现在将校验数字的思想改进一下, 使其可以对错误数据进行修复.

假设我们发送的数字是: 12341234123412134

将其每4位分开, 并分别计算其行和列的校验和. 如下图:

然后, 将其铺开进行传输: 123401234012340123404826

假如, 接收到的数据中有一位出错了, 数据变成了下面这种:

你通过计算, 发现第二行和第三列出现问题, 很快就可以定位到数字5. 计算第三列校验和: 3+5+3+3=14, 个位为4. 将5-2, 得到预测的原始数字3. 然后在计算第二行的校验和是否为0. 完成纠错. 最后将纠正后的正确的数字从中取出来. 得到原始的数据: 1234123412341234.

这种纠错方式被称为: 二维奇偶校验码.


计算机硬盘, 网络通信等都有着纠错码的身影, 它保证了数据的传输可靠. 在TCP的每个包中都存在校验和内容, 若校验出错, 则包会被直接丢弃.

简单说一下...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/508425.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机全加器简单实现

概述 用了这么久计算机, 都知道计算机有一个核心部件叫 CPU, 而 CPU中有一个小部件叫做全加器. 它是用来做什么的呢? 看名字就知道了, 做加法运算用的. 那么如何实现一个全加器呢? 你以为这又是一篇计算机内部原理的文章? 不, 放开那个女孩, 和我一起走进中学物理的课堂. …

天天看底层有什么用

疑问 其实之前我一直有个疑问, 每天工作在应用层, 就算知道 TCP 的传包, 包的校验等等, 在工作中其实是用不到的, 每天看这些东西用什么用呢? 其一, 对工作的内容其实是起不到任何作用的, 其二, 浪费的时间如果将其用在工作上是可以产出更多效益的. 那么, 带给我的到底是什么…

求最大连续子集

问题 前两天看到一道算法题, 想了几天, 然后到网上搜了搜, 基本和我想到的相契合. 来, 题目如下: 给出一个数组, 求出和最大的连续子集. 举个例子: 数组 [1, 2, 3, 4, 5] 那和最大的就是数组本身了. 但是, 如果中间出现负数, 那情况立刻就不一样了, 你需要考虑是否能够将负数…

数据压缩算法

概述 之前在听到数据压缩的时候, 想着肯定是某些高深莫测的算法, 能够完成数据的压缩这种事情, 最近看了看, 嗯, 至少咱还是能看懂的. 无损压缩 众所周知, 不管你是exe, word, txt, dmg等等, 在存储上都是以二进制进行存储的, 所以, 在讨论压缩时, 忽略文件格式即可, 只要将…

何为真何为假

还记得第一个提出日心说的人是谁么? 没错, 哥白尼. 但是在那个年代, 所有人都认为太阳围绕着地球转的年代. 哥白尼的发现打破了大家的常识, 甚至于有过了很多年, 日心说才逐渐被大众所接受. 即使到了现在, 生活中仍然留有地心说的影子, 比如"日出" “日落” 等等, 就…

TCP 三次握手的意义

概述 在网络的传输层协议中, 存在着两大悍将: TCP 和 UDP . 从前, 我傻傻的以为自己对他们虽谈不上精通, 但还是知道的, 但是, 我错了, 我被自己问住了, 我傻了. 啥也不是. UDP (这里为了介绍简单, 就不提数据在传输过程中的失真(纠错码)等情况了. 简单介绍一下, TCP才是今天…

随机数是如何生成的

引出 在现实中, 会有抛硬币猜正反的操作, 硬币要么是正, 要么是反, 在揭晓之前, 我们谁也不知道它现在的状态. 而这, 是因为其中存在着很大的不确定因素, 如抛硬币的力度、抛硬币的角度、接硬币的力度和角度、硬币的重量、当前风速等等. 但是在计算机中, 要想生成一个随机数,…

GO 文档笔记

前言 最开始写 GO 的时候, 发现方法的注释并不支持param, return等参数, 搞得我都不知道该如何给自己的方法写文档说明了. 而且网上搜了搜也没有搜到教程, 甚是郁闷. 今天找到了GO内置的文档工具: godoc. (我用的1.14.3版本貌似不是自带工具了, 需要安装(配置代理): go get g…

长整数的乘法运算

概述 都知道, 计算机中存储整数是存在着位数限制的, 所以如果需要计算100位的数字相乘, 因为编程本身是不支持存储这么大数字的, 所以就需要自己实现, 当然了, 各个编程语言都有大数的工具包, 何必重复造轮子, 但我还是忍不住好奇他们是如何实现的, 虽然最终没有翻到他们的底层…

如何将数字转换成口语中的文本串

概述 今天突发奇想, 写一个将数字转换成中文字符串的函数. 并不是将 1234 转成 1234 , 而是将 1234 转成 一千二百三十四. 本来以为很简单, 写下来之后发现还是有些坑的. 尝试 因为我是在写完最终版本, 回过头来整理的这篇文章, 所以中间很多尝试的步骤会有所遗漏. 以下简单…

设计模式故事会

想着用讲故事的方式对各个设计模式进行一个稍微形象一些的描述. 当然, 某些因为没有想到特别好的例子, 可能比喻的并不是那么的恰当, 望赐教. 绞尽脑汁啊, 尽力贴近设计模式其本来的意图. 主要为了加强一些自己对设计模式的理解. 进入正题: 小王是一名心怀梦想的90后青年, 他独…

有了 elseif 为什么还要 switch case

引出 你有没有想过既然有了if elseif, 为什么还要设计一个switch case的语法出来呢? 按理说, 一个语言的设计角度来说, 关键词越少越好吧, 而且多出来一种选择分支也没有看出太大用处. 以下几种switch case均可以写成if else的形式(java 代码): // 形式一 switch(a){case 1:…

计算矩阵中全1子矩阵的个数

前言 最近被我大哥安利了一道算法题, 这道题说难, 还不至于我做不出来, 说简单吧, 我还想不到最优解, 等把最优解告诉我之后, 我还正好能理解. 我甚至曾经怯怯的认为, 这题就是我哥专门给我找的, 嘿嘿, 心中说不出的小欢喜. 题来了, 此题出自力扣, 原题链接: https://leetco…

GO 的方法集

前言 之前在写 GOdemo 的时候, 写了这么一段程序(大概意思): package maintype Test struct { }func (test *Test) print() {println("test fun") }func main() {Test{}.print() }结果一编译就报错了: cannot call pointer method on Test literal 差不多意思是不…

GO 切片实力踩坑

概述 GO 语言的切片这两天用了用, 可以支持切割数组的中间部分. 但今天使用中, 出了 bug, 查了半天, 发现是切片的问题, 简单写个 demo 复现当时的情况: package mainimport "fmt"func main() {a : []int{1, 2, 3, 4, 5}b : a[2:4]b[0] 9fmt.Println(a) }你以为输…

搭建本地 HTTPS 环境

前言 之前写自己的网站时, 申请过免费的https证书. 最近想在自己本地搭一个, 结果忘了当初证书是怎么来的了. 本来想着去申请个免费的证书, 但想了想, 我只需要在自己本地能使用就行了, 我自己的环境, 那当然是我说了算了. 只要能够将证书构造出来, 安装到本地就可以识别了. 搜…

《人人都是产品经理》读后感

之前读书, 一般看的都是技术、算法、数学、哲学这些方面的, 为什么突然想看这本书呢? 身为一个开发人员, 每天打交道最多的, 除了开发和测试, 就是产品了. 还记得我刚来公司的时候, 在和产品的沟通过程中, 听到最多的话估计就是: 你要懂产品, 你懂了就不会做错. 确实有很多需求…

nginx 端口转发

概述 这两天在写 go 项目, 一个 HTTP 服务器. 之前写的是 php 项目, nginx 监听80端口, 根据域名将请求分配给不同项目. 现在换了 go, 自然也想延续这个操作, 毕竟都是跑在同一台服务器上. 那么问题来了, 我的nginx 监听80端口的同时, go 服务器是无法同样监听80端口的. 这该如…

2020-08-20

前段时间有些迷茫, 有时看着自己写的代码感觉就像一坨屎, 有时写了一段逻辑总是感觉有问题, 测了一遍又一遍, 逻辑也要理好几次. 就像是进入了一种不可描述的状态, 这感觉让我很不自在. 敲代码的时间说长不长, 说短不短, 从大二开始, 到现在也小四年了, 还没有碰到过这种情况. …

beego 优雅重启

前言 最近在写 go 的项目, http 用的 beego 框架. 因为 go 不想 php, 每次代码改动都需要重启服务, 所以代码发上线之后, 如何重启服务就成了一个问题. 如果强行重启的话, 不光在重启期间的所有访问都被拒绝了, 而且在杀掉进程的时候处理中的请求也挂了. 对于一个向用户正常提…