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; //数值 10 int *yu; //余数 11 int n; //数值位数 12 int YuNum; //余数位数 13 bool sym; //正负,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<<"输入数以建立对象:"<<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; //进位 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){ //异符号相减是两数绝对值相加,符号取减数 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; //减法结果出现负数 108 temp.sym = false; 109 return temp; 110 } 111 int c=0; //进位 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]; //循环中可能会用到最后一个数 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){ //大于等于的效果,跟小于对立,只比较绝对值,不关心正负 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的复制,在处理中要改变其中的值 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; //用首位相减法,跟人手酸除法的过程相似,需要改变mid中的数值和位数,m存储低位没用到的位数 209 mid.n = p.n; mid.num += this->n - p.n; //把mid置成跟p相同长度,开始相减,指针相应的向后移动 210 for( i = this->n - p.n +1-1;i >= 0; ){ 211 BigNum A = BigNum(); //A是中间变量为了使mid的数值动态化 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-- ) //去掉开头的零 220 if(mid.num[j] != 0) 221 break; 222 } 223 if( m + mid.n<p.n || m == 0 && p >mid){ //剩下的数总和比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){ //幂模运算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); //只返回正数 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算法判断大数X是否为素数,是素数返回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的源码,下面是应用范例:
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; //余数 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(对其中的数据进行加密):
599973434 2978448901 1049145034