zoukankan      html  css  js  c++  java
  • 有限域上的运算

      1 #include<iostream>
      2 #include <cstdlib>
      3 #include <ctime>
      4 #include <string>
      5 using namespace std;
      6 /*
      7  *对于多项式的,我们可以用一个二进制数来表示进行减法
      8  *例如:x^3+x+1 可以以二进制数1011来表示,即十进制数的11
      9  *本题给定既约多项式 x^8+x^4+x^3+x+1 可以通过用二进制数100011011来表示
     10  *即十进制数283
     11  *因此其生成的有限域GF(2^8)/(x^8+x^4+x^3+x+1),共有2^8=256个元素
     12  */
     13 
     14 //定义一些常量
     15 const int M = 283;  //x^8+x^4+x^3+x+1
     16 const int p = 2;   //模2
     17 const int N = 256;  //有限域内的元素个数
     18 
     19 int a,b;     //在有限域内选取的两个元素
     20 
     21 int remainvalue;  //余数式
     22 int x,y;
     23 
     24 class GFpn
     25 {
     26 public:
     27     //在有限域内部随机选取两个元素
     28     void random_element();
     29 
     30     //返回一个十进制数的二进制数的最高位
     31     int index_of_binary_max(int value);
     32 
     33     //将一个十进制数转化为对应的多项式字符串
     34     string value_into_polynomial(int value);
     35 
     36     //求一个数的2次幂,即返回2^value.
     37     int power_of_value(int value);
     38 
     39     //返回多项式的除法,remainvalue为余数
     40     int divide(int a,int b,int &remainvalue); 
     41 
     42     //相当于ax - q * bx 在多项式异或的范畴下
     43     //三元组运算
     44     int Tx(int ax,int q,int bx);
     45     
     46     //扩展的欧几里得算法
     47     //其中x返回的是b mod m的多项式的乘法逆元
     48     //所对应的的十进制数表达式
     49     int extent_gcd(int m,int b,int &x,int &y);
     50 
     51     //定义多项式有限域内的加法运算
     52     //实际上是两个数的异或
     53     int polynomial_add(int a,int b);
     54 
     55     //定义多项式有限域内的减法运算
     56     //实际上也是两个数的异或
     57     int polynomial_sub(int a,int b);
     58 
     59     //定义多项式有限域内的乘法运算
     60     //通过移位,来实现逐位异或
     61     int polynomial_mul(int a,int b);
     62 
     63     //定义多项式的除法运算
     64     //实质上也是乘以多项式在有限域的逆元
     65     int polynomial_div(int a,int b);
     66 };
     67 
     68 //在有限域中随机选取两个元素
     69 //等价为在0——N-1中随机选取两个数
     70 void GFpn::random_element()
     71 {
     72     a = rand() % N;
     73     b = rand() % N;
     74 }
     75 
     76 
     77 //求数的二进制数的最高位
     78 int GFpn::index_of_binary_max(int value)
     79 {
     80     int tmp = 1;
     81     int count = 0;
     82     int i;
     83     for(i = 0;i < sizeof(int) * 8;i++)
     84     {
     85           if(value & tmp)
     86              count = i;
     87           tmp = tmp * 2;
     88     }
     89     return count;
     90 }
     91 
     92 //将一个数转化为多项式
     93 //如:11——>1011——>x^3+x+1
     94 string GFpn::value_into_polynomial(int value)
     95 {
     96     string result;
     97     int i;
     98     int tmp = 1;
     99     int flag = 0;
    100     int c = index_of_binary_max(value);
    101     for(i = 0;i < sizeof(int) * 8;i++)
    102     {
    103           if(value & tmp)
    104           {
    105              if(i == 0)
    106              {
    107                  result += "1";
    108              }
    109              else if(i == 1)
    110              {
    111                result += "x";
    112              }
    113              else
    114              {
    115                result += "x^";
    116                result += '0'+ i;
    117              }
    118              flag = 1;
    119              if(i < c)
    120                result += "+";
    121           }   
    122           tmp = tmp * 2;
    123     }
    124     if(flag == 0)
    125       result += "0";
    126     return  result;
    127 }
    128 
    129 //求一个数的2次幂,即返回2^value.
    130 int GFpn::power_of_value(int value)
    131 {
    132     return 1 << (value);
    133 }
    134 
    135 
    136 //返回多项式的除法,remainvalue为余数
    137 int GFpn::divide(int a,int b,int &remainvalue)
    138 {
    139     int aindex = index_of_binary_max(a);
    140     int bindex = index_of_binary_max(b);
    141     if(aindex < bindex)
    142     {
    143         remainvalue = a;
    144         return 0;
    145     }
    146     int c = aindex - bindex;
    147     int tmp = b;
    148     tmp = tmp << c;
    149     a = a ^ tmp;
    150     return power_of_value(c) | divide(a,b,remainvalue);
    151 }
    152 
    153 
    154 //相当于ax - q * bx 在多项式异或的范畴下
    155 //三元组运算
    156 int GFpn::Tx(int ax,int q,int bx)
    157 {
    158     int tmp = 1;
    159     int value = 0;
    160     int i;
    161     for(i = 0;i < sizeof(int) * 8;i++)
    162     {
    163           if(q & tmp)
    164           {
    165              value = value ^ (bx << i);   
    166           }   
    167           tmp = tmp * 2;
    168     }
    169     return ax ^ value;
    170 }
    171 
    172 
    173 //扩展的欧几里得算法
    174 int GFpn::extent_gcd(int m,int b,int &x,int &y)
    175 {
    176     //先定义(a1,a2,a3)三元组
    177     int a1 = 1,a2 = 0,a3 = m;
    178     //再定义(b1,b2,b3)三元组
    179     int b1 = 0,b2 = 1,b3 = b;
    180     int remainvalue=0;
    181     while(1)
    182     {
    183         if(b3==0)
    184             return a3;
    185         if(b3==1)
    186             return b3;
    187         int q = divide(a3,b3,remainvalue);
    188         //分别定义(t1,t2,t3)三元组
    189         int t1 = Tx(a1,q,b1);     //q = a3 / b3;(多项式范畴下)
    190         int t2 = Tx(a2,q,b2);     //t1<——a1 - q * b1
    191         int t3 = remainvalue;     //t2<——a2 - q * b2
    192         //迭代过程  
    193         //(a1,a2,a3)<——(b1,b2,b3)
    194         a1 = b1;a2 = b2;a3 = b3;
    195         //(b1,b2,b3)<——(t1,t2,t3)
    196         b1 = t1;b2 = t2;b3 = t3;
    197         x = b2;
    198         y = b3; 
    199     }
    200 }
    201 
    202 //定义多项式有限域内的加法运算
    203 //实际上是两个数的异或
    204 int GFpn::polynomial_add(int a,int b)
    205 {
    206     int result;
    207     result = a ^ b;
    208     return result;
    209 }
    210 
    211 //定义多项式有限域内的减法运算
    212 //实际上也是两个数的异或
    213 int GFpn::polynomial_sub(int a,int b)
    214 {
    215     int result;
    216     result = a ^ b;
    217     return result;
    218 }
    219 
    220 //定义多项式有限域内的乘法运算
    221 //通过移位,来实现逐位异或
    222 int GFpn::polynomial_mul(int a,int b)
    223 {
    224     int result = 0;
    225     int remain = 0;
    226     int num = index_of_binary_max(b);
    227     int i;
    228     for(i = 0;i < num;i++)
    229     {
    230         if(b & 1)
    231         {
    232             result ^= a;
    233         }
    234         a <<= 1;
    235         b >>= 1;
    236     }
    237     result ^= a;
    238     result = divide(result,M,remain);
    239     return remain;
    240 }
    241 
    242 //定义多项式的除法运算
    243 //实质上也是乘以多项式在有限域的逆元
    244 int GFpn::polynomial_div(int a,int b)
    245 {
    246     int result;
    247     int aa = 0,bb = 0;
    248     int div_result = extent_gcd(M,b,aa,bb);
    249     result = polynomial_mul(a,aa);
    250     return result;
    251 }
    252 
    253 int main()
    254 {
    255     GFpn gg;
    256     //srand()函数产生一个以当前时间开始的随机种子.以保证每次产生的随机数矩阵都不相同
    257     srand((unsigned)time(0));   
    258     cout << "给定多项式: " << gg.value_into_polynomial(M) << endl;
    259     cout << endl << "生成有限域......" << endl;
    260     cout << "以下是有限域内的所有元素:"<< endl;
    261     int i;
    262     for(i = 0;i < N;i++)
    263         cout << gg.value_into_polynomial(i) << endl;
    264     cout << endl;
    265     cout << "先从所构造的有限域中随机选取两个元素,分别为:" << endl;
    266     gg.random_element();
    267     cout << gg.value_into_polynomial(a) << "" << gg.value_into_polynomial(b) << endl;
    268     cout << endl << "分别进行加减乘除运算:" << endl;
    269     cout << "加:" << "(" << gg.value_into_polynomial(a) << ") + (" << gg.value_into_polynomial(b) << ") = " 
    270         << gg.value_into_polynomial(gg.polynomial_add(a,b)) << endl;
    271     cout << endl;
    272     cout << "减:" << "(" << gg.value_into_polynomial(a) << ") - (" << gg.value_into_polynomial(b) << ") = " 
    273         << gg.value_into_polynomial(gg.polynomial_sub(a,b)) << endl;
    274     cout << endl;
    275     cout << "乘:" << "(" << gg.value_into_polynomial(a) << ") * (" << gg.value_into_polynomial(b) << ") = " 
    276         << gg.value_into_polynomial(gg.polynomial_mul(a,b)) << endl;
    277     cout << endl;
    278     cout << "除:" << "(" << gg.value_into_polynomial(a) << ") / (" << gg.value_into_polynomial(b) << ") = " 
    279         << gg.value_into_polynomial(gg.polynomial_div(a,b)) << endl;
    280     cout << endl;
    281     int a;
    282     cout << "是否还要继续:(按1退出)(按2继续)?" << endl;
    283 
    284     while(cin >> a && a != 1)
    285     {
    286         cout << "先从所构造的有限域中随机选取两个元素,分别为:" << endl;
    287         gg.random_element();
    288         cout << gg.value_into_polynomial(a) << "" << gg.value_into_polynomial(b) << endl;
    289         cout << endl << "分别进行加减乘除运算:" << endl;
    290         cout << "加:" << "(" << gg.value_into_polynomial(a) << ") + (" << gg.value_into_polynomial(b) << ") = " 
    291             << gg.value_into_polynomial(gg.polynomial_add(a,b)) << endl;
    292         cout << endl;
    293         cout << "减:" << "(" << gg.value_into_polynomial(a) << ") - (" << gg.value_into_polynomial(b) << ") = " 
    294             << gg.value_into_polynomial(gg.polynomial_sub(a,b)) << endl;
    295         cout << endl;
    296         cout << "乘:" << "(" << gg.value_into_polynomial(a) << ") * (" << gg.value_into_polynomial(b) << ") = " 
    297             << gg.value_into_polynomial(gg.polynomial_mul(a,b)) << endl;
    298         cout << endl;
    299         cout << "除:" << "(" << gg.value_into_polynomial(a) << ") / (" << gg.value_into_polynomial(b) << ") = " 
    300             << gg.value_into_polynomial(gg.polynomial_div(a,b)) << endl;
    301         cout << endl;
    302         cout << "是否还要继续:(按1退出)(按2继续)?" << endl;
    303     }
    304     return 0;
    305 }
    View Code

  • 相关阅读:
    姐姐的vue(1)
    LeetCode 64. Minimum Path Sum 20170515
    LeetCode 56. 56. Merge Intervals 20170508
    LeetCode 26. Remove Duplicates from Sorted Array
    LeetCode 24. Swap Nodes in Pairs 20170424
    LeetCode 19. Remove Nth Node From End of List 20170417
    LeetCode No.9 Palindrome Number 20170410
    LeetCode No.8. String to Integer (atoi) 2017/4/10(补上一周)
    LeetCode No.7 Reverse Integer 2017/3/27
    LeetCode No.4 Median of Two Sorted Arrays 20170319
  • 原文地址:https://www.cnblogs.com/sysu-blackbear/p/3392837.html
Copyright © 2011-2022 走看看