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

  • 相关阅读:
    小白安装使用Redis
    Mysql的Sql语句优化
    maximo入门----用户使用提要
    时不时刷刷BOSS 看看技术需求
    2019.7.10整理
    docker使用入门
    docker之windows安装&centOS安装
    HashTable学习
    Hashmap学习
    红黑树学习
  • 原文地址:https://www.cnblogs.com/sysu-blackbear/p/3392837.html
Copyright © 2011-2022 走看看