纠错码是个什么东西

引出

网络中的通信基于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位分开, 并分别计算其行和列的校验和. 如下图:

纠错码简介-LMLPHP

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

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

纠错码简介-LMLPHP

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

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


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

简单说一下...

05-10 21:07