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