zoukankan      html  css  js  c++  java
  • 大三时候实现的,关于大整数(超过long范围)加减乘除操作的头文件,并包含了实现RSA加解密的函数

      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 

  • 相关阅读:
    linux 解压tgz 文件指令
    shell 脚本没有执行权限 报错 bash: ./myshell.sh: Permission denied
    linux 启动solr 报错 Your Max Processes Limit is currently 31202. It should be set to 65000 to avoid operational disruption.
    远程查询批量导入数据
    修改 MZTreeView 赋权节点父节点选中子节点自动选中的问题
    关于乱码的问题解决记录
    我的网站优化之路
    对设计及重构的一点反思
    我的五年岁月
    奔三的路上
  • 原文地址:https://www.cnblogs.com/zhidian314/p/2615201.html
Copyright © 2011-2022 走看看