FEC-Reed-Solomon算法浅析(一)

前言

本文是介绍FEC-Reed—Solomon算法的第一篇,主要介绍伽罗华域的相关知识,因为这个伽罗华域算是这个算法能够广泛被应用在网络通信的大功臣来,我们先来看看伽罗华域是什么。先介绍下创造这个域的人,伽罗华(也译作伽瓦罗),法国数学家,群论的创立者。用群论彻底解决了根式求解代数方程的问题,而且由此发展了一整套关于群和域的理论。这个人比较悲惨的是他死于与其他人的决斗当中,不得不说有点可惜。好了,让我们进入正题。

相关数据概念

一组元素的集合,以及在集合上的四则运算,构成一个域。其中加法和乘法必须满足交换、结合和分配的规律。加法和乘法具有封闭性,即加法和乘法结果仍然是域中的元素。域中必须有加法单位元和乘法单位元,且每一个元素都有对应的加法逆元和乘法逆元。但不要求域中的 0有乘法逆元。

有限域

仅含有限多个元素的域。因为它由伽罗华所发现,因而又称为伽罗华域。所以当我们说伽罗华域的时候,就是指有限域。GF(2^w)表示包含有2^w个元素的有限域。

单位元

Identity Element,通常使用e来表示单位元。单位元和其他元素结合时,并不会改变那些元素。 对于二元运算,若ae=a,e称为右单位元;若ea=a,e称为左单位元,若ae=e*a=a,则e称为单位元。(有点类似于矩阵里面的单位矩阵概念)

逆元

对于二元运算,若ab=e,则a称为b的左逆元素,b称为a的右逆元素。若ab=ba=e,则称a为b的逆元,b为a的逆元。

素多项式

域中不可约多项式是不能够进行因子分解的多项式,素多项式(primitive polynomial)是一种特殊的不可约多项式。当一个域上的素多项式确定了,这个域上的运算也就确定了。素多项式一般通过查表可得,同一个域往往有多个素多项式。通过将域中的元素化为多项式形式,可以将域上的乘法运算转化为普通的多项式乘法再模素多项式。

多项式运算

GF(2^w)下多项式运算

这里不再介绍基本的多项式乘法,这里只介绍一下GF(2^w)下的多项式运算,对于GF(2^w)上的多项式计算,多项式系数只能取0或1。(如果是GF(2^w),那么系数可以取 0、1、2,GF(2^w)的多项式加法中,合并阶数相同的同类项时,由于0+0=0,1+1=0,0+1=1+0=1,因此系数不是进行加法操作,而是进行异或操作。

GF(2^w)的多项式减法等于加法,例如x^4x^4就等于x^4 + x^4进而等于0,因为1+1=1^1=0。

伽罗华域

有限域GF(p)

有限域GF(p),其中p为素数。GF(p)里面的加法和乘法与一般的加法和乘法差不多,区别是结果需要mod p,以保证结果都是域中的元素。GF(p)的加法和乘法单位元分别是 0和1。 GF(p)加法是(a+b) mod p,乘法是(a*b)mod p。

对于域中的乘法,当p为素数时,才能保证集合中的所有的元素都有乘法逆元(0除外)。即对于域中的任一个元素a,总能在域中找到另外一个元素b,使得a*b mod p 等于1。

说明:假如p等于10,其乘法单位元为1。对于元素2,找不到一个数a,使得2*a mod 10 等于1,即2没有乘法逆元。这时,在域上就不能进行除2运算。

有限域GF(2^w)

GF(p)中p必须是一个素数,才能保证集合中的所有元素都有加法和乘法逆元(0除外)。但实际应用中,很多场合需要 0到255这256个数字能组成一个域。但256不是素数,小于256的最大素数为251,如果直接把大于等于251的数截断为250,则会丢失一部分数据。

因此引入了GF(p^w),其中p为素数,通常取p=2。计算机领域中经常使用的是GF(2^8),8刚好是一个字节的比特数。为了保证有限域性质,GF(2^w)上的加法运算和乘法运算,不再使用一般的加法和乘法,而是使用多项式运算。

这里的核心就是GF(2^8),因为这个就是我们所需要的,2^8大小正好是一个字节,说明我们终于能对一个字节下手了(笑),现在下一个问题就是我们应该怎么知道在GF(2^8)上应该如何运算呢?下面我们引入之前说过的素多项式

GF(2^8)下的素多项式

伽罗华域的元素可以通过该域上的素多项式生成。通过本原多项式得到的域,其加法单位元都是 0,乘法单位元是1。

以GF(2^3)为例,指数小于3的多项式共8个:0,1,x,x+1,x^2x^2+1,x^2 + x x^2+x+1。其系数刚好就是000,001, 010, 011, 100, 101, 110, 111,是0到7这8个数的二进制形式。

GF(2^3)上有不只一个素多项式,但是我们随便选一个素多项式x^3+x+1,这8个多项式进行四则运算后mod(x^3+x+1)的结果都是8个之中的某一个。因此这8个多项式构成一个有限域。

对于GF(2^3),取素多项式为x^3+x+1,那么多项式x^2+x的乘法逆元就是x+1。系数对应的二进制分别为110和011。此时,我们就认为对应的十进制数6和3互为逆元。

部分 GF(2^w)域经常使用的本原多项式如下:

image.png

通过素多项式来生成元素

设P(x)是GF(2^w)上的某一个本原多项式,GF(2^w)的元素产生步骤是:

  1. 给定一个初始集合,包含0,1,即 {0,1}
  2. 将这个集合中的最后一个元素,即x,乘以x,如果结果的度大于等于w,则将结果mod P(x)后加入集合
  3. 直到集合有2^w个元素,此时最后一个元素乘以x再mod P(x)的值等于1

这里我仍然以GF(2^3)为例子,素多项式为x^3+x+1,GF(2^3)共有8个元素,除了0、1之外,其他元素都由按照上面的步骤来生成:

生成元素 多项式表示 二进制表示 十进制表示
0 0 0 0
x^0 1 001 1
x^1 x^1 010 2
x^2 x^2 100 4
x^3 x+1 011 3
x^4 x^2 + x 110 6
x^5 x^2+x+1 111 7
x^6 x^2 + 1 101 5
x^7 1 1 1

这里推导过程我就不给出了,其实mod P(x)本质就是将加上P(x)即x^3+x+1,由于加法操作是异或操作,所以x^3项就被消去了,保证了结果多项式的最高次数不超过3,转换成2进制表示也就不超过8,保证了结果一定是落在[0,7]这个区间内,实际上0是不可能出现的,因为x^3+x+1是素多项式。

伽罗华域GF(2^8)上的线性运算

加法运算

这个比较简单,就是异或运算,同时需要注意的是减法就是加法,都是异或运算

乘法和除法运算

这个稍微复杂一点,伽罗华域上的多项式乘法,其结果需要mod P(x),本质就是加上素多项式x^8=x^4+x^3+x^2+1,除法其实就是乘法的逆运算,除以一个数就等于乘以这个数的逆元。
GF(2^8)符号的表示形式如下:

image.png

这个在计算机计算的时候为了避免大量的计算,一般会采用查表的方式来进行计算,现在的问题就是我们如何获得这个表呢?这里就得先说下如何计算了:
对于一般形式的多项式f(x)=a7\*x^7 + a6\*x^6 + a5\*x^5 + a4\*x^4 + a3\*x^3 + a2\*x^2 + a1x + a0,乘以x得到 xf(x) = (a7\*x^8 + a6\*x^7 + a5\*x^6 + a4\*x^5 + a3\*x^4 + a2\*x^3 + a1\*x^1 + a0x) mod P(x)
这时有两种情况:

  1. a7 == 0,此时结果是一个小于指数小于8的多项式,不需要取模计算。

  2. a7 == 1,则将x^8替换为x^4 + x^3 + x^2 +1,而不用进行除法取模计算,结果为:xf(x) = (x^4 + x^3 + x^2 +1) + a6x^7 + a5x^6 + a4x^5 + a3x^4 + a2x^3 + a1x^1 + a0x,实际上由于我们计算的GF(2^8),所以系数的取值只能为0或1。

下面我给出表的生成算法:

int MM = 8;
int NN = 255;
int alphaToMM = 45;//α^8=α^5+α^3+α^2+1
int* alphaTo = new int[NN+1];
int* expOf = new int[NN+1];

alphaTo[MM] = alphaToMM;
expOf[alphaToMM] = MM;
alphaTo[NN] = 0;
expOf[0] = NN;

int i, shift;
shift = 1;
///在计算指数从1到7的情况
for(i=0; i<MM; i++){
    alphaTo[i] = shift;//2^i
    expOf[alphaTo[i]] = i;
    shift <<= 1;
}
shift = 128;
///计算指数高于7次的情况
for(i=MM+1; i<NN; i++){
   if(alphaTo[i-1] >= shift){
      ///说明多项式的最高次数已经达到7,对应的是上面说的a7==1的情况
      alphaTo[i] = alphaTo[MM] ^ ((alphaTo[i-1]^shift)<<1);//alphaTo[i-1]*alpha+alpha^8
    }else{
      ///说明多项式的最高次数没有到7,直接移位就好
      alphaTo[i] = alphaTo[i-1]<<1;
    }
   expOf[alphaTo[i]] = i;
}

关于除法运算,这里其实也比较简单,对于一个给定的多项式比如D(x),如果想要找到它的逆元,先求它对应的指数,即expOf[D(x)],然后计算用255-expOf[D(x)],令结果是k吧,也就是k=255-expOf[D(x)],其实D(x)的逆元就是alphaTo[k],这个比较简单,这里我就不再多说

总结

说到这里伽罗华域就说的差不多了,之后还有两篇文章介绍范德蒙矩阵和实际的一个使用FEC的例子,有全部的计算过程辅助理解。

参考

伽罗华域
GF(2^8)的生成算法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270