大三时候实现的,关于大整数(超过long范围)加减乘除操作的头文件,并包含了实现RSA加解密的函数...
生活随笔
收集整理的這篇文章主要介紹了
大三时候实现的,关于大整数(超过long范围)加减乘除操作的头文件,并包含了实现RSA加解密的函数...
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1 #include<iostream>
2 #include<time.h>
3 #include<string.h>
4 using namespace std;
5
6
7 class BigNum{
8 private:
9 int *num; //數(shù)值
10 int *yu; //余數(shù)
11 int n; //數(shù)值位數(shù)
12 int YuNum; //余數(shù)位數(shù)
13 bool sym; //正負(fù),true為正
14 public:
15 BigNum(char *str){
16 n = strlen(str);
17 YuNum = 0;sym = true;
18 num = new int[strlen(str)];
19 for(int i = 0 ; i < strlen(str) ; i++)
20 num[i] = str[strlen(str)-i-1]-'0';
21 }
22 BigNum(int A){
23 int i,j;
24 int a = A;
25 for(i=0; a!=0; i++)
26 a/=10;
27 num = new int[i];
28 a = A;
29 for(j=0; j<i; j++){
30 num[j] = a%10;
31 a/=10;
32 }
33 n = i;
34 YuNum = 0;
35 }
36 BigNum(bool a){
37 YuNum = 0;sym = true;
38 char *str = new char[256];
39 cout<<"輸入數(shù)以建立對(duì)象:"<<endl;
40 cin>>str;
41 n = strlen(str);
42 num = new int[strlen(str)];
43 for(int i = 0 ; i < strlen(str) ; i++)
44 num[i] = str[strlen(str)-i-1]-'0';
45 }
46 BigNum(){
47 sym = true;
48 n = 0;
49 YuNum = 0;
50 }
51 BigNum operator+(BigNum p){
52 BigNum temp = BigNum();
53 int i;
54 if( this->sym + p.sym == 1){
55 bool s;
56 if(*this > p){
57 s = this->sym;
58 this->sym = p.sym;
59 temp = *this - p;
60 temp.sym = s;
61 }
62 else{
63 s = p.sym;
64 p.sym = this->sym;
65 temp = p - *this;
66 temp.sym = s;
67 }
68 return temp;
69 }
70 int c=0; //進(jìn)位
71 temp.n = max(this->n ,p.n );
72 int *Num = new int[temp.n +1 ];
73 for( i=0; i<min(this->n ,p.n); i++){
74 Num[i]= (this->num[i] +p.num[i] +c) %10;
75 c = (this->num[i]+p.num[i]+c)/10;
76 }
77 if(this->n > p.n)
78 for( i = p.n ; i < temp.n ; i++){
79 Num[i] = (this->num[i]+c)%10;
80 c = (this->num[i]+c)/10;
81 }
82 else
83 for( i=this->n;i<p.n;i++){
84 Num[i] = (p.num[i]+c)%10;
85 c = (p.num[i]+c)/10;
86 }
87 if(c>0){
88 temp.n++;
89 Num[temp.n-1]=c;
90 }
91 temp.num = new int[temp.n];
92 for(int i=0;i<temp.n;i++)
93 temp.num[i] = Num[i];
94 return temp;
95 }
96 BigNum operator-(BigNum p){
97 BigNum temp = BigNum();
98 int i;
99 if(this->sym + p.sym == 1){ //異符號(hào)相減是兩數(shù)絕對(duì)值相加,符號(hào)取減數(shù)
100 bool s = this->sym;
101 this->sym = p.sym;
102 temp = *this + p;
103 temp.sym = s;
104 return temp;
105 }
106 if(!(*this > p)){
107 temp = p - *this; //減法結(jié)果出現(xiàn)負(fù)數(shù)
108 temp.sym = false;
109 return temp;
110 }
111 int c=0; //進(jìn)位
112 int *Num = new int[this->n];
113 for( i=0;i<this->n;i++){
114 if(i<p.n){
115 if(this->num[i]+c>=p.num[i]){
116 Num[i] = this->num[i]+c-p.num[i];
117 c=0;
118 }
119 else{
120 Num[i] = this->num[i]+c+10-p.num[i];
121 c=-1;
122 }
123 }
124 else{
125 if(this->num[i]+c>=0){
126 Num[i] = this->num[i]+c;
127 c = 0;
128 }
129 else{
130 Num[i] = this->num[i]+c+10;
131 c = -1;
132 }
133 }
134 }
135 temp.n = this->n;
136 for( i=this->n-1;Num[i]==0&&i>=0;i--)
137 temp.n--;
138 temp.num = new int[temp.n];
139 for( i=0;i<temp.n;i++)
140 temp.num[i] = Num[i];
141 return temp;
142 }
143 BigNum operator*(BigNum p){
144 int i;
145 BigNum temp = BigNum();
146 if(this->sym + p.sym == 1)
147 temp.sym = false;
148 if(this->n==0 || p.n==0)
149 return temp;
150 int *Num = new int[p.n+this->n+1]; //循環(huán)中可能會(huì)用到最后一個(gè)數(shù)
151 int c = 0;
152 for(i=0; i < this->n+p.n; i++)
153 Num[i] = 0;
154 for(i=0; i < p.n+this->n; i++){
155 for(int j=0; j < this->n; j++)
156 for(int k=0; k < p.n; k++){
157 if(i==j+k)
158 c += this->num[j]*p.num[k];
159 }
160 Num[i]+=c%10;
161 c=c/10;
162 }
163 for(i=this->n+p.n; Num[i] <= 0; )
164 i--;
165 temp.n=i+1;
166 temp.num = new int[temp.n];
167 for(i=0; i<temp.n; i++)
168 temp.num[i] = Num[i];
169 return temp;
170 }
171 bool operator> (BigNum p){ //大于等于的效果,跟小于對(duì)立,只比較絕對(duì)值,不關(guān)心正負(fù)
172 if(this->n > p.n)
173 return true;
174 else if(this->n < p.n)
175 return false;
176 else{
177 for(int i=1 ; i <= p.n; i++){
178 if(this->num[n-i] == p.num[n-i])
179 continue;
180 else if(this->num[n-i] <= p.num[n-i])
181 return false;
182 else
183 return true;
184 }
185 return true;
186 }
187 }
188 BigNum operator/(BigNum p){
189 BigNum temp = BigNum();
190 int i,j,k;
191 temp.sym = this->sym + p.sym;
192 if(!(*this > p)){
193 temp.n = 0;
194 temp.yu = new int[this->n];
195 temp.YuNum = this->n;
196 for( i=0;i<this->n;i++)
197 temp.yu[i] = this->num[i];
198 return temp;
199 }
200 int *Num = new int[this->n-p.n+1];
201 for( i=0;i<this->n-p.n+1;i++) //置零
202 Num[i] = 0;
203 BigNum mid = BigNum(); //讓mid成為this的復(fù)制,在處理中要改變其中的值
204 mid.n = this->n;
205 mid.num = new int[mid.n];
206 for( i = 0; i < mid.n; i++)
207 mid.num[i] = this->num[i];
208 int m = mid.n - p.n; //用首位相減法,跟人手酸除法的過(guò)程相似,需要改變mid中的數(shù)值和位數(shù),m存儲(chǔ)低位沒(méi)用到的位數(shù)
209 mid.n = p.n; mid.num += this->n - p.n; //把mid置成跟p相同長(zhǎng)度,開(kāi)始相減,指針相應(yīng)的向后移動(dòng)
210 for( i = this->n - p.n +1-1;i >= 0; ){
211 BigNum A = BigNum(); //A是中間變量為了使mid的數(shù)值動(dòng)態(tài)化
212 while( mid > p ){
213 A = mid - p;
214 for( k=0; k < A.n ; k++)
215 mid.num[k] = A.num[k];
216 for( k=A.n; k < mid.n; k++)
217 mid.num[k] = 0;
218 Num[i] +=1;
219 for( j = mid.n-1; j >= 0 ;j--,mid.n-- ) //去掉開(kāi)頭的零
220 if(mid.num[j] != 0)
221 break;
222 }
223 if( m + mid.n<p.n || m == 0 && p >mid){ //剩下的數(shù)總和比P小,除法完成
224 temp.yu = new int[m + mid.n];
225 mid.num -= m;
226 for( k = 0; k < m + mid.n ; k++)
227 temp.yu[k] = mid.num[k];
228 temp.YuNum = m + mid.n;
229 //mid.n = this->n;
230 int j = this->n - p.n + 1;
231 for( ; j>0 ; j--)
232 if(Num[j-1] != 0)
233 break;
234 temp.num = new int[j];
235 for( k = 0;k < j ; k++ )
236 temp.num[k] = Num[k];
237 temp.n = j;
238 return temp;
239 }
240 else{
241 m -= p.n - mid.n;
242 mid.num -= p.n - mid.n;
243 i -= p.n - mid.n;
244 mid.n = p.n;
245 if( m > 0 && p > mid){ //借位
246 m--;
247 i--;
248 mid.num--;
249 mid.n++;
250 }
251 for( k = mid.n ; mid.num[k-1] == 0 && k >= 1 ; k--)
252 mid.n--;
253 }
254 }
255 return temp;
256 }
257 void display(){
258 int i;
259 if( sym == false )
260 cout<<'-';
261 for( i=0 ;i < n; i++)
262 cout<<num[n-i-1];
263 if(YuNum > 0){
264 cout<<endl;
265 for( i=0; i < YuNum; i++)
266 cout<<yu[YuNum-i-1]<<' ';
267 }
268 cout<<endl;
269 }
270 static void swap(BigNum &a,BigNum &b){
271 BigNum temp = a;
272 a = b;
273 b=temp;
274 }
275 static BigNum gcd(BigNum A,BigNum B){
276 int i;
277 BigNum temp;
278 BigNum a;a = A;
279 BigNum b;b = B;
280 while(true){
281 temp = a/b;
282 if( a>b )
283 BigNum::swap( a,b );
284 free(b.num);
285 b.n = temp.YuNum;
286 b.num = new int[a.n];
287 for( i=0;i < temp.YuNum; i++){
288 b.num[i] = temp.yu[i];
289 }
290 if( temp.YuNum==0 )
291 break;
292 }
293 return a;
294 }
295 void operator=(BigNum p){
296 int i;
297 this->~BigNum();
298 this->sym = p.sym;
299 this->n = p.n;
300 this->num = new int[this->n];
301 for( i=0; i< p.n; i++)
302 this->num[i] = p.num[i];
303 this->YuNum = p.YuNum;
304 this->yu = new int[this->YuNum];
305 for( i=0; i< p.YuNum; i++)
306 this->yu[i] = p.yu[i];
307 }
308 static BigNum inv(BigNum a, BigNum b){ //小的放在前面
309 BigNum a0 = a;
310 BigNum b0 = b;
311 BigNum t0;
312 BigNum t("1");
313 BigNum s0("1");
314 BigNum s;
315 BigNum q = a0 /b0;
316 BigNum r = a0 - (q * b0);
317 BigNum temp;
318 while( r > BigNum("1") ){
319 temp = t0 - (q * t);
320 t0 = t;
321 t = temp;
322 temp = s0 - (q * s);
323 s0 = s;
324 s = temp;
325 a0 = b0;
326 b0 = r;
327 q = a0 /b0;
328 r = a0 - (q * b0);
329 }
330 r = b0;
331 if( s.sym == false )
332 s = s + b;
333 return s;
334 }
335 bool operator==(BigNum p){
336 if( this->n == p.n ){
337 for(int i=0; i < p.n; i++)
338 if( this->num[i] != p.num[i] )
339 return false;
340 return true;
341 }
342 return false;
343 }
344 char* toChar(){
345 int i;
346 char *str = new char[this->n+2];
347 for(i=0; i<this->n; i++)
348 str[this->n-i-1] = '0'+this->num[i];
349 str[i] = '\0';
350 return str;
351 }
352 BigNum mod(BigNum n){
353 BigNum temp;
354 if(!(*this> n)){
355 temp.n = this->n;
356 temp.num = new int[temp.n];
357 for(; temp.n>0; temp.n--)
358 temp.num[temp.n-1] = this->num[temp.n-1];
359 temp.n = this->n;
360 }
361 else{
362 BigNum y = *this /n;
363 temp.n = y.YuNum;
364 temp.num = new int[temp.n];
365 for( ; temp.n>0; temp.n--)
366 temp.num[temp.n-1] = y.yu[temp.n-1];
367 temp.n = y.YuNum;
368 }
369 return temp;
370 }
371 static BigNum Square_and_Multiply(BigNum X, BigNum C, BigNum N){ //冪模運(yùn)算z = x^c(mod n)
372 int i;
373 BigNum x = X;BigNum c = C;BigNum n = N;
374 BigNum two("2");
375 for(i=0; c.n>0; i++)
376 c = c /two;
377 bool *bol = new bool[i];
378 c = C;
379 for(i=0; c.n>0; i++){
380 c = c /two;
381 if(c.YuNum > 0)
382 bol[i] = 1;
383 else
384 bol[i] = 0;
385 }
386 BigNum z("1");
387 for( ; i >0; i--){
388 z = (z*z).mod(n); //只返回正數(shù)
389 if(bol[i-1] == 1)
390 z = (z*x).mod(n);
391 }
392 return z;
393 }
394 static bool Miller_Rabin(BigNum X){ //Miller Rabin算法判斷大數(shù)X是否為素?cái)?shù),是素?cái)?shù)返回true
395 int i,k;
396 BigNum x = X;
397 BigNum two("2");
398 x = x - BigNum("1");
399 for(k=0; x.YuNum==0; k++){
400 x = x /two;
401 }
402 BigNum m = x*two + BigNum("1");
403 k= k- 1;
404 BigNum b = Square_and_Multiply(BigNum("2"),m,X);
405 x = X - BigNum("1");
406 if( b==BigNum("1")) return true;
407 for(i=0; i<k; i++){
408 if( b==x)
409 return true;
410 else
411 b = Square_and_Multiply(b,two,X);
412 }
413 return false;
414 }
415 static BigNum create_prime(int m){
416 int i;
417 BigNum num("1");
418 BigNum one("1");
419 BigNum two("2");
420 srand(time(0));
421 for(i=0; i<m-1; i++){
422 num = num* two + BigNum(rand()).mod(two);
423 }
424 BigNum temp;
425 while(true){
426 temp = num;
427 for(i=1; temp>two; i++)
428 temp = temp /two;
429 if(Miller_Rabin(num)&&i==m)
430 return num;
431 else if(i>m){
432 num = create_prime(m);
433 return num;
434 }
435 else
436 num = num+ two;
437 }
438 }
439 };
以上是BigNum.h的源碼,下面是應(yīng)用范例:
1 #include"BigNum.h" 2 #include<fstream> 3 4 void main(){ 5 char *str = new char[256]; 6 cout<<"輸入密鑰";cin>>str; 7 BigNum c = BigNum(str); 8 cout<<"輸入n";cin>>str; 9 BigNum n = BigNum(str); 10 ifstream in("data.txt"); 11 ofstream out("result.txt"); 12 BigNum x; 13 BigNum y; 14 char g; 15 while(!in.eof()){ 16 in.get(str,100,' '); 17 if(!(in.eof())) 18 in.get(g); 19 x = BigNum( str ); 20 y = BigNum::Square_and_Multiply(x, c, n); 21 out<<y.toChar()<<' '; 22 y.display(); 23 } 24 /*string ss; 25 BigNum data; 26 BigNum yu; //余數(shù) 27 BigNum sh; //商 28 BigNum one("1"); 29 while( !in.eof() ){ 30 in>>num; 31 sh = BigNum("1"); 32 data = BigNum(num); 33 for( BigNum i = BigNum("1") ; k >i; i =i +one){ 34 sh = sh * data; 35 yu = sh / n; 36 //free(temp->num); 37 sh.~BigNum(); 38 sh =BigNum(); 39 sh.n =yu.YuNum; 40 sh.num = new int[sh.n]; 41 for(int j = 0; j < yu.YuNum ; j++){ 42 sh.num[j] = yu.yu[j]; 43 } 44 //free(temp->yu);temp->YuNum =0; 45 } 46 sh.display(); 47 out<<sh.toChar()<<' '; 48 }*/ 49 in.close(); 50 out.close(); 51 getchar(); 52 getchar(); 53 }其中需要文件data.txt(對(duì)其中的數(shù)據(jù)進(jìn)行加密):
599973434 2978448901 1049145034?
轉(zhuǎn)載于:https://www.cnblogs.com/zhidian314/archive/2012/07/30/2615201.html
總結(jié)
以上是生活随笔為你收集整理的大三时候实现的,关于大整数(超过long范围)加减乘除操作的头文件,并包含了实现RSA加解密的函数...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一家三口幸福的句子发朋友圈说说心情 秀一
- 下一篇: RHEL4-SFTP配置