Reed_Solumon 编码

来源:互联网 发布:电脑软件的用处 编辑:程序博客网 时间:2024/05/04 13:05

reed_solumon 编码是纠错编码技术之一,在通讯技术里和磁盘存储系统里常用。简单说就是在原有信息里加入冗余信息,让信息在传输中更加稳健。让我们把信息传输比喻成小鸭鸭过河,一个小鸭鸭过河很容易被水浪冲走,一群小鸭鸭手挽手过河,就会多一份机会完好无损地度过去,这就是稳健。具体在通讯传输中,如果我们要传输数据123,可能由于噪声影响传过去变成了120, 如果没有加入reed_solumon编码,信息就出错了。如果我们在传输123时,加入冗余信息,比如我们传三遍原有信息,这样传输的数据就变成123123123,由于噪声干扰,我们的到了120 123123,虽然传输的123 变成了120,但是看到后面的两个123,我们知道传输的实际上是123而不是120,于是120123123就被纠正成123123123,去除后面的冗余码123123,我们就得到了实际上纠正过的传输码123。所以纠错编码的基本概念就是在原有信息里加入冗余信息一起传输,在接收方用相应的算法把原有信息算出来,冗余信息去除。这中间当然需要有些算法,我们举的信息重复的例子(123变成123123123)只是为了让大家明白编码的原理,实际中的算法有许多种(比如Reed Solomon和 CRC等),要面对不同的情况,解决不同的问题,但是万变不离其宗,不管算法如何,概念都是加入冗余,再逆运算去除冗余的过程。明白了这个原理再看算法,就不会觉得那么难了。


需要说明的是纠错有两个概念,一个是发现错误,一个是纠正错误,如果收到信息后进行反变换,能够得到吻合的信息,说明信号没有被噪声污染,如果不能通过反变换恢复,我们就知道信号某些位在传输或储存时受噪声干扰出错了,如果错误少于一定数量的位数,可以用算法被纠正过来,大于一定位数的错误,就只能找到错误而不能完全修复错误了。另外加入的冗余位也是有可能受噪声影响而出错的,这个时候纠错就不能正确进行了,有些方法可以避免或者减少这种情况出现的概率,以后我们慢慢讨论。


编码也从做开始


记得写过一篇没有结尾的博文(脸红一下),叫做学习傅立叶变换从做开始。其实无论学习任何理论,最有效的方法都是从做开始了。


我们既然知道了编码的过程和目的,不如自己先试着做一个编码,从而更详细地知道编码的过程,也就知道我们从直观上得出的编码过程问题在哪里,为什么会有那些理论来支持编码过程了。


最直观的想法,我们要传输的都是整数,先把GF域等编码里常看到的数学理论放一放,想想如果我们要传输一堆整数,需要加入冗余信息让传输更加稳健,我们会怎么做。除了最开始说的重复方法(传输123123123来代替123),我还能想到以下这个方法。

Berlekamp-Massey decodingalgorithm

假定传输的三个数是2  8 10, 我把他们用多项式算一下再传输,比如这个多项式是


http://en.wikipedia.org/wiki/Reed%E2%80%93Solomon_error_correction#Berlekamp.E2.80.93Massey_decoder


http://en.wikipedia.org/wiki/Berlekamp%E2%80%93Massey_algorithm#Berlekamp.E2.80.93Massey_algorithm_for_fields


http://en.wikipedia.org/wiki/Forney_algorithm



我们知道编码的过程就是


编码也从做开始


关于域的概念

因为我们传输和储存的是数据块,而且我们希望所传输的数据无论怎么编码解码,都在可控制的一个封闭区域内,以保证编码解码的正确性,这忍不住让我们想到数学里的域(field),它就具备这样的特性。


数学里的域是一个代数结构,也就是一个数据集合(有限集),或者表,域里的数字满足一定的运算规律,比如加法和乘法是闭运算,也满足加法乘法交换律和结合律,每个非零元素都有乘法逆元(任一非零元素都存在1/a,使得a * (1/a) = 1)等。例如有理数复数实数都是fields,也有其他的例子,比如质数p,以它为模的所有整数(integer mod p,也就是所有运算遵循p-1进制规律)组成一个集合,这个集合也是一个field。注意复数和有理数集都是域,但是整数集却不是,因为整数集里的元素没有逆元,比如2是整数集里的元素,但1/2却不是,所以2在整数集里没有逆元,整数集不是域,而是环,有兴趣的同学可以在网上查阅有关信息。


域的表示方法--多项式表示法

既然域是数字的集合,而且是有限集合;同时要满足一些闭运算的条件,也就是运算后的元素还是这个域的元素;最重要的,因为我们是要用电脑操作和计算这些数据,不能产生溢出, 而且最好能一目了然地知道多少位可以储存这些域里面的数字。这些要求都让我们觉得用指数形式表示这些数字比较合适,比如234用十进制表示为2x10^2 + 3 x 10^1 + 4x10^0,因为电脑储存的都是二进制数,我们用二进制会更加直观于是234被写成11101010,也就是 1x2^7 + 1x2^6 + 1x2^5 + 0x2^4 + 1x2^3 + 0x2^2 + 1x2^1 + 0x2^0。无论是2x10^2 + 3 x 10^1 + 4x10^0 还是1x2^7 + 1x2^6 + 1x2^5 + 0x2^4 + 1x2^3 + 0x2^2 + 1x2^1 + 0x2^0,他们都是域元素的多项式形式表示法,这样域里面元素之间的运算就可以通过这些多项式的运算来实现,


一些必须清楚的概念


REED SOLOMON编码是从消息(MESSAGE)到码字(codeword)转换的过程。

假如消息是(m1,m2,...,mm)







GF(Galois fields)


说到REED SOLOMON编码,不得不先说到GF,


数学里field的定义:它是一个代数结构,也就是一个表,满足加法乘法交换律和结合律等运算规律。例如有理数复数实数都是fields,也有其他的例子,如质数p,以它为模的所有整数(integer mod p,也就是所有运算遵循p-1进制规律)组成一个集合,这个集合就是field,加法乘法之后结果仍在这个field,假如这个质数是3(integer mod 3),那么这个field就是0 1 2,也就是0,20,21
所以一个mod xk+1的field,我们可以用一个多项式来表示field里所有元素的值。mo+ m1x+, . . . ,+ mK-2xk-2+mK-1xk-1