zoukankan      html  css  js  c++  java
  • RSA加密算法 C++实现

        上信息安全课,老师布置了几个大作业,其中一个为RSA加密算法的实现,不能用Java写。出于兴趣,决定尝试。完成之后,为了便于查找,于是写下这篇文章,以备后续查看。也供大家一起学习,一起进步。

    1、预备知识

    1.1 快速幂算法

        顾名思义,快速幂就是快速算底数的$n$次幂。其时间复杂度为${ m{O(log n)}}$,与朴素的$Oleft( n ight)$相比,效率有了极大的提高。具体可以参考百度百科:快速幂

    1.2 扩展欧几里得算法

        扩展欧几里得算法(英语:Extended Euclidean algorithm)是欧几里得算法(又叫辗转相除法)的扩展。已知整数a、b,扩展欧几里得算法可以在求得a、b的最大公约数的同时,能找到整数x、y(其中一个很可能是负数),使它们满足贝祖等式

    [ax{ m{ }} + { m{ }}by{ m{ }} = { m{ }}gcdleft( {a,b} ight).]

        如果$a$是负数,可以把问题转化成

        $left| a ight|left( { - x} ight){ m{ }} + { m{ }}by{ m{ }} = { m{ }}gcdleft( {left| a ight|,b} ight)$($left| a ight|$为a的绝对值),然后令$xprime { m{ }} = { m{ }}left( { - x} ight)$。具体可以参考维基百科:扩展欧几里得

    1.3 米勒-拉宾素性检验算法

        要测试${ m{N}}$是否为素数,首先将${ m{N - 1}}$分解为${2^s}d$。在每次测试开始时,先随机选一个介于$[1,N - 1]$的整数$a$,之后如果对所有的$r in [0,s - 1]$,若${a^d}mod N e 1$且${a^{{2^r}d}}mod N e  - 1$,则$N$是合数。否则,$N$有$3/4$的概率为素数。

        构成该算法的思想是,如果${a^d} e 1left( {{ m{mod n}}} ight)$以及$n = 1{ m{ }} + { m{ }}{2^s}d$是素数,则值序列

    [{a^d}mod n,{a^{2d}}mod n,{a^{4d}}mod n, ldots ,{a^{{2^s}d}}mod n]

        将以$1$结束,而且在头一个$1$的前边的值将是$n-1$(当$p$是素数时,对于${y^2} equiv 1left( {mod p} ight)$,仅有的解是$y equiv  pm 1left( {mod p} ight)$,因为$left( {y + 1} ight)left( {y - 1} ight)$必须是$p$的倍数)。注意,如果在该序列中出现了$n-1$,则该序列中的下一个值一定是$1$,因为${left( {n-1} ight)^2} equiv {n^2}-2n + 1 equiv 1left( {mod n} ight)$。具体可以参考维基百科:米勒-拉宾素性检验

    1.4 RSA加密算法

    1.4.1 公钥与私钥的产生

        假设Alice想要通过一个不可靠的媒体接收Bob的一条私人消息。她可以用以下的方式来产生一个公钥和一个私钥:

        1、随意选择两个大的质数$p$和$q$,$p$不等于$q$,计算$N = pq$。

        2、根据欧拉函数,求得$r = varphi (N) = varphi (p)varphi (q) = (p - 1)(q - 1)$。

        3、选择一个小于$r$的整数$e$,使$e$与$r$互质。并求得$e$关于$r$的模反元素,命名为$d$(求$d$令$ed equiv 1(mod ;r)$)。(模反元素存在,当且仅当$e$与$r$互质)

        4、将$p$和$q$的记录销毁。

        $left( {N,e} ight)$是公钥,$left( {N,d} ight)$是私钥。Alice将她的公钥$left( {N,e} ight)$传给Bob,而将她的私钥$left( {N,d} ight)$藏起来。

    1.4.2 加密消息

        假设Bob想给Alice送一个消息$m$,他知道Alice产生的$N$和$e$。他使用起先与Alice约好的格式将$m$转换为一个小于$N$,且与$N$互质的整数$n$,比如他可以将每一个字转换为这个字的Unicode码,然后将这些数字连在一起组成一个数字。假如他的信息非常长的话,他可以将这个信息分为几段,然后将每一段转换为$n$。用下面这个公式他可以将$n$加密为$c$:

    [{n^e} equiv c({ m{mod;}}N)]

        计算$c$并不复杂。Bob算出$c$后就可以将它传递给Alice。

    1.4.3 解密消息

        Alice得到Bob的消息$c$后就可以利用她的密钥$d$来解码。她可以用以下这个公式来将$c$转换为$n$:

    [{c^d} equiv n({ m{mod;}}N)]

        得到$n$后,她可以将原来的信息$m$重新复原。

        解码的原理是

    [{c^d} equiv {n^{ed}}({ m{mod}}:N)]

        已知$ed equiv 1(mod ;r)$,即$ed = 1 + hvarphi (N)$。由欧拉定理得:

    [{n^{ed}} = {n^{1 + hvarphi (N)}} = n{left( {{n^{varphi (N)}}} ight)^h} equiv n{(1)^h}(mod ;N) equiv n(mod ;N)]

        RSA也可用作数字签名。具体可以参考维基百科:RSA

    2、模块设计

    2.1 BigInteger类

        因为该加密算法涉及的数可能很大,而C++中并没有像Java一样,内置大整数类BigInteger,故需自己实现,我的实现大概是模仿Java的BigInteger设计的。

        该模块包含两个文件:BigInteger.h和BigInteger.cpp。代码如下所示。

        BigInteger.h代码如下。

      1 /**
      2  * @Name    : BigInteger.h
      3  * @Date    : 2017-04-11-22.11.39
      4  * @Author  : Silenceneo (silenceneo_xw@163.com)
      5  * @Link    : http://www.cnblogs.com/Silenceneo-xw/
      6  * @Version : 2.0
      7  */
      8 
      9 #ifndef __BIGINTEGER_H__
     10 #define __BIGINTEGER_H__
     11 
     12 #include <string>
     13 #include <vector>
     14 #include <ostream>
     15 class BigInteger {
     16 public:
     17     typedef long long long_t;
     18     typedef unsigned base_t;
     19     BigInteger(): is_negative(false) { data.push_back(0); }// 默认为0
     20     BigInteger(const BigInteger &);    // 利用给定的大整数初始化
     21     BigInteger(const std::string &);// 利用给定的十六进制字符串初始化
     22     BigInteger(const long_t &);        // 利用给定的long_t类型数据初始化
     23     ~BigInteger() {}
     24 
     25     BigInteger add(const BigInteger &);        // 大整数加法
     26     BigInteger subtract(const BigInteger &);// 大整数减法
     27     BigInteger multiply(const BigInteger &) const;// 大整数乘法
     28     BigInteger divide(const BigInteger &);    // 大整数整除
     29     BigInteger remainder(const BigInteger &);    // 大整数取余
     30     BigInteger mod(const BigInteger &);        // 大整数取模
     31     BigInteger divideAndRemainder(const BigInteger &, BigInteger &);// 大整数整除和取余
     32     BigInteger pow(const BigInteger &);        // 大整数幂乘
     33     BigInteger modPow(const BigInteger &, const BigInteger &) const;// 大整数幂模运算
     34     BigInteger modInverse(const BigInteger &);// 用扩展欧几里得算法求乘法逆元
     35 
     36     BigInteger shiftLeft(const unsigned);    // 移位运算,左移
     37     BigInteger shiftRight(const unsigned);    // 移位运算,右移
     38 
     39     int compareTo(const BigInteger &) const;// 比较运算
     40     bool equals(const BigInteger &) const;// 判断是否等于给定数
     41     static BigInteger valueOf(const long_t &);// 将给定数转换为大整数并返回
     42     std::string toString() const;    // 将大整数转换为十六进制字符串
     43     BigInteger abs() const;        // 求大整数的绝对值
     44 protected:
     45     // 以下运算符重载函数主要用于像基本类型一样使用大整数类型
     46     friend BigInteger operator + (const BigInteger &, const BigInteger &);
     47     friend BigInteger operator - (const BigInteger &, const BigInteger &);
     48     friend BigInteger operator * (const BigInteger &, const BigInteger &);
     49     friend BigInteger operator / (const BigInteger &, const BigInteger &);
     50     friend BigInteger operator % (const BigInteger &, const BigInteger &);
     51     friend bool operator < (const BigInteger &, const BigInteger &);
     52     friend bool operator > (const BigInteger &, const BigInteger &);
     53     friend bool operator == (const BigInteger &, const BigInteger &);
     54     friend bool operator <= (const BigInteger &, const BigInteger &);
     55     friend bool operator >= (const BigInteger &, const BigInteger &);
     56     friend bool operator != (const BigInteger &, const BigInteger &);
     57 
     58     // 重载版本,使其能用于long_t类型
     59     friend BigInteger operator + (const BigInteger &, const long_t &);
     60     friend BigInteger operator - (const BigInteger &, const long_t &);
     61     friend BigInteger operator * (const BigInteger &, const long_t &);
     62     friend BigInteger operator / (const BigInteger &, const long_t &);
     63     friend BigInteger operator % (const BigInteger &, const long_t &);
     64     friend bool operator < (const BigInteger &, const long_t &);
     65     friend bool operator > (const BigInteger &, const long_t &);
     66     friend bool operator == (const BigInteger &, const long_t &);
     67     friend bool operator <= (const BigInteger &, const long_t &);
     68     friend bool operator >= (const BigInteger &, const long_t &);
     69     friend bool operator != (const BigInteger &, const long_t &);
     70 
     71     friend std::ostream & operator << (std::ostream &, const BigInteger &);
     72     BigInteger operator = (const std::string & str) { return (*this) = BigInteger(str); }
     73     BigInteger operator = (const long_t & num) { return (*this) = BigInteger(num); }
     74 private:
     75     BigInteger trim();    // 去掉高位无用的0
     76     int hexToNum(char);    // 十六进制字符转换为十进制数
     77 public:
     78     static const int base_bit = 5;    // 2^5=32,大整数每位存储的二进制位数
     79     static const int base_char = 8;    // 组成大整数的一位需要的十六进制位数
     80     static const int base_int = 32;    // 大整数一位对应的二进制位数
     81     static const int base_num = 0xffffffff;// 截取低位的辅助
     82     static const int base_temp = 0x1f;    // 截取模32的余数的辅助
     83     static const BigInteger ZERO;    // 大整数常量0
     84     static const BigInteger ONE;    // 大整数常量1
     85     static const BigInteger TWO;    // 大整数常量2
     86     static const BigInteger TEN;    // 大整数常量10
     87 private:
     88     bool is_negative;// 是否为负数
     89     std::vector<base_t> data;// 按位数据存储,高位在后
     90     class bit {    // 便于大整数运算的二进制处理类
     91     public:
     92         bit(const BigInteger &);// 根据大整数初始化
     93 
     94         size_t size() { return length; }    // 返回大整数对应的二进制位数
     95         bool at(size_t);    // 返回第i位二进制是否为1
     96     private:
     97         std::vector<base_t> bit_vector;    // 二进制数据存储,每一个元素对应32位二进制
     98         size_t length;    // 二进制的总位数
     99     };
    100     friend class RSA;    // RSA为其友元类
    101 };
    102 
    103 #endif // __BIGINTEGER_H__
    View Code

        BigInteger.cpp代码如下。

      1 /**
      2  * @Name    : BigInteger.cpp
      3  * @Date    : 2017-04-11-22.16.42
      4  * @Author  : Silenceneo (silenceneo_xw@163.com)
      5  * @Link    : http://www.cnblogs.com/Silenceneo-xw/
      6  * @Version : 2.0
      7  */
      8 
      9 #include <algorithm>
     10 #include <cassert>
     11 #include <cctype>
     12 #include "BigInteger.h"
     13 
     14 // 以下表示为静态常量赋值
     15 const BigInteger BigInteger::ZERO = BigInteger(0);
     16 const BigInteger BigInteger::ONE = BigInteger(1);
     17 const BigInteger BigInteger::TWO = BigInteger(2);
     18 const BigInteger BigInteger::TEN = BigInteger(10);
     19 
     20 /**
     21  * 函数功能:根据给定的大整数构造一个新的大整数
     22  * 参数含义:val代表给定的大整数
     23  */
     24 BigInteger::BigInteger(const BigInteger & val) {
     25     *this = val;
     26 }
     27 
     28 /**
     29  * 函数功能:根据给定的十六进制字符串数据构造一个大整数
     30  * 参数含义:str代表给定的数据
     31  */
     32 BigInteger::BigInteger(const std::string & str): is_negative(false) {
     33     std::string t(str);
     34     if (t.size() && t.at(0)=='-') {
     35         if (t.size() > 1)
     36             is_negative = true;
     37         t = t.substr(1);
     38     }
     39     int cnt = (8-(t.size()%8))%8;// 数的长度不是8的倍数,补足0
     40     std::string temp;
     41 
     42     for (int i=0; i<cnt; ++i)
     43         temp.push_back('0');
     44 
     45     t = temp+t;
     46 
     47     for (size_t i=0; i<t.size(); i+=base_char) {
     48         base_t sum = 0;
     49         for (int j=0; j<base_char; ++j) {    // 8位十六进制组成大整数的一位
     50             char ch = t[i+j];
     51             int num = hexToNum(ch);
     52             sum = ((sum<<4) | (num));
     53         }
     54         data.push_back(sum);
     55     }
     56     reverse(data.begin(), data.end());// 高位在后
     57     *this = trim();// 去除高位的0
     58 }
     59 
     60 /**
     61  * 函数功能:根据给定的long_t类型数据构造一个大整数
     62  * 参数含义:num代表给定的数据
     63  */
     64 BigInteger::BigInteger(const long_t & num): is_negative(false) {
     65     long_t t = num;
     66     if (t < 0) {
     67         is_negative = true;
     68         t = -t;
     69     }
     70     do {
     71         base_t temp = (t&base_num);    // 每次截取低32位
     72         data.push_back(temp);
     73         t >>= base_int;
     74     } while (t);
     75 }
     76 
     77 /**
     78  * 函数功能:大整数加法运算
     79  * 参数含义:val代表加数
     80  */
     81 BigInteger BigInteger::add(const BigInteger & val) {
     82     BigInteger ans(*this);
     83     if (ans.is_negative == val.is_negative) {// 同号
     84         int len = val.data.size()-ans.data.size();
     85 
     86         while ((len--) > 0)    // 被加数位数少,高位补0
     87             ans.data.push_back(0);
     88 
     89         int carry = 0;    // 进位
     90         for (size_t i=0; i<val.data.size(); ++i) {
     91             base_t temp = ans.data[i];
     92             ans.data[i] += val.data[i]+carry;    // 无符号数相加,超出取其余数
     93             // 进位:一种是有无进位都超出,一种是有进位才超出(比如十进制相加,9+9+1,得9,9+0+0,得9)
     94             carry = (temp>ans.data[i] ? 1 : (temp>(temp+val.data[i]) ? 1 : 0));
     95         }
     96 
     97         for (size_t i=val.data.size(); i<ans.data.size() && carry!=0; ++i) {// 还有进位
     98             base_t temp = ans.data[i];
     99             ans.data[i] += carry;
    100             carry = temp > ans.data[i];
    101         }
    102 
    103         if (carry)    // 还有进位
    104             ans.data.push_back(carry);
    105     }
    106     else {    // 异号
    107         BigInteger a = abs();
    108         BigInteger b = val.abs();
    109         int flag = a.compareTo(b);
    110         // 绝对值相等,则结果为0,否则用绝对值大的减去小的,符号随绝对值大的
    111         if (flag == -1) {
    112             ans = b.subtract(a);
    113             ans.is_negative = val.is_negative;
    114         }
    115         else if (flag == 0)
    116             ans = ZERO;
    117         else {
    118             ans = a.subtract(b);
    119             ans.is_negative = is_negative;
    120         }
    121     }
    122     return ans;
    123 }
    124 
    125 /**
    126  * 函数功能:大整数减法运算
    127  * 参数含义:val代表减数
    128  */
    129 BigInteger BigInteger::subtract(const BigInteger & val) {
    130     BigInteger ans(*this);
    131     BigInteger a = abs();
    132     BigInteger b = val.abs();
    133     if (ans.is_negative == val.is_negative) {// 同号
    134         int flag = a.compareTo(b);
    135         if (flag == 1) {// a的绝对值大于b的绝对值,直接减
    136             int borrow = 0;    // 借位
    137             // 大数减小数
    138             for (size_t i=0; i<val.data.size(); ++i) {
    139                 base_t temp = ans.data[i];
    140                 ans.data[i] -= val.data[i]+borrow;
    141                 // 借位:一种是有无借位都超出,另一种是有借位才超出(比如十进制相减,9-0-0,得9,9-9-1,得9)
    142                 borrow = temp<ans.data[i] ? 1 : (temp-borrow<val.data[i] ? 1 : 0);
    143             }
    144             for (size_t i=val.data.size(); i<ans.data.size() && borrow!=0; ++i) {// 还有借位
    145                 base_t temp = ans.data[i];
    146                 ans.data[i] -= borrow;
    147                 borrow = temp < (base_t)borrow;
    148             }
    149             ans = ans.trim();// 去掉高位多余的0
    150         }
    151         else if (flag == 0)
    152             ans = ZERO;
    153         else {// a的绝对值小于b的绝对值
    154             ans = b.subtract(a);
    155             ans.is_negative = !is_negative;
    156         }
    157     }
    158     else {    // 异号
    159         ans = a.add(b);    // 转换为加法
    160         ans.is_negative = is_negative;
    161     }
    162     return ans;
    163 }
    164 
    165 /**
    166  * 函数功能:大整数乘法运算
    167  * 参数含义:val代表乘数
    168  */
    169 BigInteger BigInteger::multiply(const BigInteger & val) const {
    170     if (equals(ZERO) || val.equals(ZERO))
    171         return ZERO;
    172     // 将位数少的作为乘数
    173     const BigInteger & big = data.size()>val.data.size() ? (*this) : val;
    174     const BigInteger & small = (&big)==(this) ? val : (*this);
    175 
    176     BigInteger ans;
    177     bit t(small);    // 转换为二进制进行运算
    178 
    179     for (int i=t.size()-1; i>=0; --i)
    180         if (t.at(i)) {
    181             BigInteger temp(big);
    182             temp.is_negative = false;
    183             temp = temp.shiftLeft(i);    // 移位对齐
    184             ans = ans.add(temp);
    185         }
    186     ans.is_negative = !(is_negative == val.is_negative);
    187     return ans;
    188 }
    189 
    190 /**
    191  * 函数功能:大整数整除运算
    192  * 参数含义:val代表除数
    193  */
    194 BigInteger BigInteger::divide(const BigInteger & val) {
    195     BigInteger temp;
    196     BigInteger ans = divideAndRemainder(val, temp);
    197     return ans;
    198 }
    199 
    200 /**
    201  * 函数功能:大整数取余运算
    202  * 参数含义:val代表除数
    203  */
    204 BigInteger BigInteger::remainder(const BigInteger & val) {
    205     BigInteger ans;
    206     divideAndRemainder(val, ans);
    207     return ans;
    208 }
    209 
    210 /**
    211  * 函数功能:大整数取模运算(不同于取余,该函数总是返回正余数)
    212  * 参数含义:m代表模数
    213  */
    214 BigInteger BigInteger::mod(const BigInteger & m) {
    215     BigInteger ans = remainder(m);
    216     if (ans.is_negative)
    217         ans = ans.add(m);
    218     return ans;
    219 }
    220 
    221 /**
    222  * 函数功能:大整数整除运算和取余运算,整除结果直接返回,取余结果由m传回
    223  * 参数含义:val表示除数,m表示取余结果
    224  */
    225 BigInteger BigInteger::divideAndRemainder(const BigInteger & val, BigInteger & m) {
    226     assert(!val.equals(ZERO));
    227     BigInteger a = abs();
    228     BigInteger b = val.abs();
    229     int flag = a.compareTo(b);
    230     if (flag == 0)// 绝对值相等
    231         return (is_negative==val.is_negative) ? BigInteger(1) : BigInteger(-1);
    232     if (flag == -1) {
    233         m = *this;
    234         return ZERO;
    235     }
    236     BigInteger ans;
    237 
    238     bit bit_b(b);
    239     // 位数对齐
    240     while (true) {// a的绝对值大于b的绝对值
    241         bit bit_a(a);
    242         int len = bit_a.size()-bit_b.size();
    243         BigInteger temp;
    244         // 找到移位
    245         while (len >= 0) {
    246             temp = b.shiftLeft(len);
    247             if (temp.compareTo(a) != 1)// 找到最大的左移位数使得当前的a大于等于b
    248                 break;
    249             --len;
    250         }
    251         if (len < 0)    // 当前的a小于b了
    252             break;
    253         base_t num = 0;
    254         while (temp.compareTo(a) != 1) {
    255             a = a.subtract(temp);
    256             ++num;    // 统计当前的a最多大于等于几个移位后的b
    257         }
    258         temp = BigInteger(num);
    259         if (len)
    260             temp = temp.shiftLeft(len);// 移位后表明当前的a是b的几倍
    261         ans = ans.add(temp);
    262     }
    263     ans.is_negative = !(is_negative==val.is_negative);
    264     m.data = a.data;
    265     m.is_negative = is_negative;
    266     return ans;
    267 }
    268 
    269 /**
    270  * 函数功能:大整数幂乘运算
    271  * 参数含义:exponent代表指数
    272  */
    273 BigInteger BigInteger::pow(const BigInteger & exponent) {
    274     BigInteger ans(1);
    275     bit t(exponent);    // 转化为二进制,快速求幂
    276     for (int i=t.size()-1; i>=0; --i) {
    277         ans = ans.multiply(ans);
    278         if (t.at(i))
    279             ans = multiply(ans);// 从高位开始,位权累加效应
    280     }
    281     return ans;
    282 }
    283 
    284 /**
    285  * 函数功能:大整数模幂运算
    286  * 参数含义:exponent代表指数,m代表模数
    287  */
    288 BigInteger BigInteger::modPow(const BigInteger & exponent, const BigInteger & m) const {
    289     assert(!m.equals(ZERO));
    290     BigInteger ans(1);
    291     bit t(exponent);
    292     for (int i=t.size()-1; i>=0; --i) {
    293         ans = ans.multiply(ans).mod(m);
    294         if (t.at(i))
    295             ans = multiply(ans).mod(m);
    296     }
    297     return ans;
    298 }
    299 
    300 /**
    301  * 函数功能:扩展欧几里得算法求乘法逆元
    302  * 参数含义:m代表求逆元时的模数
    303  */
    304 BigInteger BigInteger::modInverse(const BigInteger & m) {
    305     assert(!is_negative);    // 当前大整数为正数
    306     assert(!m.is_negative);    // m为正数
    307     if (equals(ZERO) || m.equals(ZERO))
    308         return ZERO;    // 有一个数为0,就不存在乘法逆元
    309     BigInteger a[3], b[3], t[3];
    310     // 以下进行初等变换
    311     a[0] = 0; a[1] = 1; a[2] = *this;
    312     b[0] = 1; b[1] = 0; b[2] = m;
    313 
    314     for (t[2]=a[2].mod(b[2]); !t[2].equals(ZERO); t[2]=a[2].mod(b[2])) {
    315         BigInteger temp = a[2].divide(b[2]);
    316         for (int i=0; i<3; ++i) {
    317             t[i] = a[i].subtract(temp.multiply(b[i]));// 不超过一次a[2]-temp*b[2]就变为大数减小数
    318             a[i] = b[i];
    319             b[i] = t[i];
    320         }
    321     }
    322     if (b[2].equals(ONE)) {// 最大公约数为1,存在乘法逆元
    323         if (b[1].is_negative)// 逆元为负数
    324             b[1] = b[1].add(m);// 变为正数,使其在m的剩余集中
    325         return b[1];
    326     }
    327     return ZERO;// 最大公约数不为1,无乘法逆元
    328 }
    329 
    330 /**
    331  * 函数功能:移位运算,左移
    332  * 参数含义:len代表移位的位数
    333  */
    334 BigInteger BigInteger::shiftLeft(const unsigned len) {
    335     int index = len>>base_bit;    // 大整数每一位需要移动多少位
    336     int shift = len&base_temp;    // 还剩下多少位
    337     BigInteger ans(*this);
    338 
    339     int inc = (shift==0) ? index : index+1;// 有多余的位要多开大整数的一位
    340     for (int i=0; i<inc; ++i)
    341         ans.data.push_back(0);    // 高位补0
    342 
    343     if (index) {
    344         inc = (shift==0) ? 1 : 2;// 有多余的位要预留一位
    345         for (int i=ans.data.size()-inc; i>=index; --i)
    346             ans.data[i] = ans.data[i-index];
    347         for (int i=0; i<index; ++i)
    348             ans.data[i] = 0;
    349     }
    350     if (shift) {
    351         base_t t = base_num;
    352         t <<= base_int-shift;    // 用于截取高位
    353         // 左移
    354         base_t temp = 0;
    355         for (size_t i=0; i<ans.data.size(); ++i) {
    356             base_t tmp = ans.data[i];
    357             ans.data[i] = (tmp<<shift) | temp;// 左移后加上大整数低位的高位
    358             temp = (tmp&t)>>(base_int-shift);// 获取该大整数位的高位
    359         }
    360     }
    361     ans = ans.trim();
    362     return ans;
    363 }
    364 
    365 /**
    366  * 函数功能:移位运算,右移
    367  * 参数含义:len代表移位的位数
    368  */
    369 BigInteger BigInteger::shiftRight(const unsigned len) {
    370     bit val(*this);
    371     if (len >= val.size())// 当前大整数位数小于等于移位位数,返回0
    372         return ZERO;
    373     int index = len>>base_bit;// 大整数每一位需要移动多少位
    374     int shift = len&base_temp;// 还剩下多少位
    375     BigInteger ans(*this);
    376 
    377     if (index) {
    378         for (int i=0; i<index; ++i)
    379             ans.data[i] = ans.data[i+index];
    380         for (int i=0; i<index; ++i)
    381             ans.data.pop_back();    // 高位删除
    382     }
    383     if (shift) {
    384         base_t t = base_num;
    385         t >>= base_int-shift;    // 用于截取低位
    386         // 右移
    387         base_t temp = 0;
    388         for (int i=ans.data.size()-1; i>=0; --i) {
    389             base_t tmp = ans.data[i];
    390             ans.data[i] = (tmp>>shift) | temp;// 右移后加上大整数高位的低位
    391             temp = (tmp&t)<<(base_int-shift);// 获取该大整数位的低位
    392         }
    393     }
    394     ans = ans.trim();
    395     return ans;
    396 }
    397 
    398 /**
    399  * 函数功能:大整数比较函数,-1表示本大整数要小,0表示相等,1表示本大整数要大
    400  * 参数含义:val代表要与之比较的大整数
    401  */
    402 int BigInteger::compareTo(const BigInteger & val) const {
    403     if (is_negative != val.is_negative) {// 符号不同,负数必小
    404         if (is_negative == true)
    405             return -1;
    406         return 1;
    407     }
    408     int flag = 0;
    409     if (data.size() < val.data.size())// 位数较小
    410         flag = -1;
    411     else if (data.size() > val.data.size())// 位数较大
    412         flag = 1;
    413     else {    // 位数相等,从高位开始一一比较
    414         for (std::vector<base_t>::const_reverse_iterator it=data.rbegin(), ite=val.data.rbegin(); it!=data.rend(); ++it, ++ite)
    415             if ((*it) != (*ite)) {
    416                 flag = (*it)<(*ite) ? -1 : 1;    // 高位小,则小
    417                 break;
    418             }
    419     }
    420     if (is_negative)    // 如为负数,小的反而大
    421         flag = -flag;
    422     return flag;
    423 }
    424 
    425 /**
    426  * 函数功能:大整数是否相等函数
    427  * 参数含义:val表示要与之比较的大整数
    428  */
    429 bool BigInteger::equals(const BigInteger & val) const {
    430     return (is_negative==val.is_negative) && (data==val.data);// 符号和数据都要相等
    431 }
    432 
    433 /**
    434  * 函数功能:将一个long_t类型的数据转换为大整数并返回
    435  * 参数含义:num表示给定的数
    436  */
    437 BigInteger BigInteger::valueOf(const long_t & num) {
    438     return BigInteger(num);
    439 }
    440 
    441 /**
    442  * 函数功能:将大整数转换为十六进制字符串并返回
    443  */
    444 std::string BigInteger::toString() const {
    445     std::string ans;
    446     base_t t = base_num;
    447     t <<= base_int-4;    // 用于截取高4位
    448     for (int i=data.size()-1; i>=0; --i) {
    449         base_t temp = data[i];
    450         for (int j=0; j<base_char; ++j) {
    451             base_t num = t&temp;// 每次截取高4位
    452             num >>= base_int-4;    // 将高4位移到低4位
    453             temp <<= 4;
    454             if (num < 10)
    455                 ans.push_back((char)('0'+num));
    456             else
    457                 ans.push_back((char)('A'+num-10));
    458         }
    459     }
    460     while (ans.size()>0 && ans.at(0)=='0')// 去掉高位无用的0
    461         ans = ans.substr(1);
    462     if (ans.empty())    // 空串说明为0
    463         ans.push_back('0');
    464     if (is_negative)    // 为负数加上负号
    465         ans = "-"+ans;
    466     return ans;
    467 }
    468 
    469 /**
    470  * 函数功能:返回大整数的绝对值
    471  */
    472 BigInteger BigInteger::abs() const {
    473     BigInteger ans;
    474     ans.data = data;// 只复制数据,符号默认为正
    475     return ans;
    476 }
    477 
    478 // 以下运算符重载函数主要是为了使得能使用
    479 // 大整数类型像使用基本类型一样,不一一介绍
    480 BigInteger operator + (const BigInteger & a, const BigInteger & b) {
    481     BigInteger t(a);
    482     return t.add(b);
    483 }
    484 
    485 BigInteger operator - (const BigInteger & a, const BigInteger & b) {
    486     BigInteger t(a);
    487     return t.subtract(b);
    488 }
    489 
    490 BigInteger operator * (const BigInteger & a, const BigInteger & b) {
    491     BigInteger t(a);
    492     return t.multiply(b);
    493 }
    494 
    495 BigInteger operator / (const BigInteger & a, const BigInteger & b) {
    496     BigInteger t(a);
    497     return t.divide(b);
    498 }
    499 
    500 BigInteger operator % (const BigInteger & a, const BigInteger & b) {
    501     BigInteger t(a);
    502     return t.remainder(b);
    503 }
    504 
    505 bool operator < (const BigInteger & a, const BigInteger & b) {
    506     return a.compareTo(b) == -1;
    507 }
    508 
    509 bool operator > (const BigInteger & a, const BigInteger & b) {
    510     return b < a;
    511 }
    512 
    513 bool operator == (const BigInteger & a, const BigInteger & b) {
    514     return a.equals(b);
    515 }
    516 
    517 bool operator <= (const BigInteger & a, const BigInteger & b) {
    518     return !(a > b);
    519 }
    520 
    521 bool operator >= (const BigInteger & a, const BigInteger & b) {
    522     return !(a < b);
    523 }
    524 
    525 bool operator != (const BigInteger & a, const BigInteger & b) {
    526     return !(a == b);
    527 }
    528 
    529 BigInteger operator + (const BigInteger & a, const BigInteger::long_t & b) {
    530     return a+BigInteger(b);
    531 }
    532 
    533 BigInteger operator - (const BigInteger & a, const BigInteger::long_t & b) {
    534     return a-BigInteger(b);
    535 }
    536 
    537 BigInteger operator * (const BigInteger & a, const BigInteger::long_t & b) {
    538     return a*BigInteger(b);
    539 }
    540 
    541 BigInteger operator / (const BigInteger & a, const BigInteger::long_t & b) {
    542     return a/BigInteger(b);
    543 }
    544 
    545 BigInteger operator % (const BigInteger & a, const BigInteger::long_t & b) {
    546     return a%BigInteger(b);
    547 }
    548 
    549 bool operator < (const BigInteger & a, const BigInteger::long_t & b) {
    550     return a < BigInteger(b);
    551 }
    552 
    553 bool operator > (const BigInteger & a, const BigInteger::long_t & b) {
    554     return a > BigInteger(b);
    555 }
    556 
    557 bool operator == (const BigInteger & a, const BigInteger::long_t & b) {
    558     return a == BigInteger(b);
    559 }
    560 
    561 bool operator <= (const BigInteger & a, const BigInteger::long_t & b) {
    562     return a <= BigInteger(b);
    563 }
    564 
    565 bool operator >= (const BigInteger & a, const BigInteger::long_t & b) {
    566     return a >= BigInteger(b);
    567 }
    568 
    569 bool operator != (const BigInteger & a, const BigInteger::long_t & b) {
    570     return a != BigInteger(b);
    571 }
    572 
    573 std::ostream & operator << (std::ostream & out, const BigInteger & val) {
    574     out << val.toString();
    575     return out;
    576 }
    577 
    578 /**
    579  * 函数功能:创建该大整数的一个副本,去除掉高位无用的0后并返回
    580  */
    581 BigInteger BigInteger::trim() {
    582     size_t cnt = 0;
    583     // 检查高位为0的元素的数量
    584     for (std::vector<base_t>::const_reverse_iterator it=data.rbegin(); it!=data.rend(); ++it) {
    585         if ((*it) == 0)
    586             ++cnt;
    587         else
    588             break;
    589     }
    590     if (cnt == data.size())    // 只有零的情况保留
    591         --cnt;
    592     BigInteger ans(*this);
    593     for (size_t i=0; i<cnt; ++i)
    594         ans.data.pop_back();
    595     return ans;
    596 }
    597 
    598 /**
    599  * 函数功能:根据给定的字符确定它所对应的十进制数
    600  * 参数含义:ch代表给定的字符
    601  */
    602 int BigInteger::hexToNum(char ch) {
    603     int ans = 0;
    604     if (isdigit(ch))
    605         ans = ch-'0';
    606     else if (islower(ch))
    607         ans = ch-'a'+10;
    608     else
    609         ans = ch-'A'+10;
    610     return ans;
    611 }
    612 
    613 /**
    614  * 函数功能:根据给定的大整数初始化
    615  * 参数含义:val代表给定的大整数
    616  */
    617 BigInteger::bit::bit(const BigInteger & val) {
    618     bit_vector = val.data;
    619     base_t temp = bit_vector[bit_vector.size()-1];// 大整数最高位
    620     length = bit_vector.size()<<base_bit;    // 大整数一位占二进制32位
    621     base_t t = 1<<(base_int-1);    // 用于截取一个数的二进制最高位
    622 
    623     if (temp == 0)    // 大整数最高位为0,减去32
    624         length -= base_int;
    625     else {
    626         while (!(temp & t)) {// 从高位开始检测大整数的二进制位,为0长度减一
    627             --length;
    628             t >>= 1;    // 右移一位表示检测下一位
    629         }
    630     }
    631 }
    632 
    633 /**
    634  * 函数功能:检测大整数的第id位二进制位是否为1
    635  * 参数含义:id代表第id位
    636  */
    637 bool BigInteger::bit::at(size_t id) {
    638     size_t index = id>>base_bit;// 确定其在大整数第几位
    639     size_t shift = id&base_temp;// 确定其在大整数那一位的二进制第几位
    640     base_t t = bit_vector[index];
    641     return (t & (1<<shift));
    642 }
    View Code

    2.2 RSA类

        该类主要实现RSA相关功能,例如加密和解密等。

        该模块也有两个文件:RSA.h和RSA.cpp。代码如下所示。

        RSA.h代码如下。

     1 /**
     2  * @Name    : RSA.h
     3  * @Date    : 2017-04-11-22.25.57
     4  * @Author  : Silenceneo (silenceneo_xw@163.com)
     5  * @Link    : http://www.cnblogs.com/Silenceneo-xw/
     6  * @Version : 2.0
     7  */
     8 
     9 #ifndef __RSA_H__
    10 #define __RSA_H__
    11 
    12 #include <ostream>
    13 #include "BigInteger.h"
    14 class RSA {
    15 public:
    16     RSA() {}
    17     RSA(const unsigned len) { init(len); }    // 利用len初始化对象
    18     ~RSA() {}
    19 
    20     void init(const unsigned);// 初始化,产生公私钥对
    21 
    22     BigInteger encryptByPublic(const BigInteger &);    // 公钥加密
    23     BigInteger decryptByPrivate(const BigInteger &);// 私钥解密
    24 
    25     // 以下主要用于数字签名
    26     BigInteger encryptByPrivate(const BigInteger &);// 私钥加密
    27     BigInteger decryptByPublic(const BigInteger &);    // 公钥解密
    28 protected:
    29     friend std::ostream & operator << (std::ostream &, const RSA &);// 输出相关数据
    30 private:
    31     BigInteger createOddNum(unsigned);// 生成一个大奇数,参数为其长度
    32     bool isPrime(const BigInteger &, const unsigned);// 判断是否为素数
    33     BigInteger createRandomSmaller(const BigInteger &);// 随机创建一个更小的数
    34     BigInteger createPrime(unsigned, const unsigned);// 生成一个大素数,参数为其长度
    35     void createExponent(const BigInteger &);// 根据提供的欧拉数生成公钥、私钥指数
    36 public:
    37     BigInteger n, e;// 公钥
    38 private:
    39     BigInteger d;// 私钥
    40     BigInteger p, q;// 大素数p和q
    41     BigInteger eul;// n的欧拉函数
    42 };
    43 
    44 #endif // __RSA_H__
    View Code

        RSA.cpp代码如下。

      1 /**
      2  * @Name    : RSA.cpp
      3  * @Date    : 2017-04-11-22.27.51
      4  * @Author  : Silenceneo (silenceneo_xw@163.com)
      5  * @Link    : http://www.cnblogs.com/Silenceneo-xw/
      6  * @Version : 2.0
      7  */
      8 
      9 #include <cassert>
     10 #include <sstream>
     11 #include <ctime>
     12 #include "RSA.h"
     13 
     14 /**
     15  * 函数功能:初始化RSA对象的相关信息
     16  * 参数含义:len表示大素数的二进制位数
     17  */
     18 void RSA::init(const unsigned len) {
     19     srand((unsigned)time(NULL));
     20     // 产生大素数p和q
     21     p = createPrime(len, 15);// 出错概率为(1/4)^15
     22     q = createPrime(len, 15);
     23     // 计算出n
     24     n = p*q;
     25     // 计算出n的欧拉函数
     26     eul = (p-1)*(q-1);
     27     // 设置加解密指数e和d
     28     createExponent(eul);
     29 }
     30 
     31 /**
     32  * 函数功能:使用公钥进行加密
     33  * 参数含义:m表示要加密的明文
     34  */
     35 BigInteger RSA::encryptByPublic(const BigInteger & m) {
     36     return m.modPow(e, n);
     37 }
     38 
     39 /**
     40  * 函数功能:使用私钥进行解密
     41  * 参数含义:c表示要解密的密文
     42  */
     43 BigInteger RSA::decryptByPrivate(const BigInteger & c) {
     44     return c.modPow(d, n);
     45 }
     46 
     47 /**
     48  * 函数功能:使用私钥进行加密
     49  * 参数含义:m表示要加密的明文
     50  */
     51 BigInteger RSA::encryptByPrivate(const BigInteger & m) {
     52     return decryptByPrivate(m);
     53 }
     54 
     55 /**
     56  * 函数功能:使用公钥进行解密
     57  * 参数含义:c表示要解密的密文
     58  */
     59 BigInteger RSA::decryptByPublic(const BigInteger & c) {
     60     return encryptByPublic(c);
     61 }
     62 
     63 /**
     64  * 函数功能:输出RSA相关数据
     65  * 参数含义:out表示输出流,rsa表示要输出的RSA对象
     66  */
     67 std::ostream & operator << (std::ostream & out, const RSA & rsa) {
     68     out << "n: " << rsa.n << "
    ";
     69     out << "p: " << rsa.p << "
    ";
     70     out << "q: " << rsa.q << "
    ";
     71     out << "e: " << rsa.e << "
    ";
     72     out << "d: " << rsa.d;
     73     return out;
     74 }
     75 
     76 /**
     77  * 函数功能:生成一个长度为len的奇数
     78  * 参数含义:len代表奇数的二进制长度
     79  */
     80 BigInteger RSA::createOddNum(unsigned len) {
     81     static const char hex_table[] = {'0', '1', '2', '3', '4', '5', '6', '7',
     82                                     '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
     83     len >>= 2;    // 十六进制数据,每位占4位二进制
     84     if (len) {
     85         std::ostringstream oss;
     86         for (size_t i=0; i<len-1; ++i)
     87             oss << hex_table[rand()%16];
     88         oss << hex_table[1];// 最后一位为奇数
     89         return BigInteger(oss.str());
     90     }
     91     return BigInteger("F");
     92 }
     93 
     94 /**
     95  * 函数功能:判断一个数是否为素数,采用米勒拉宾大素数检测算法,失误率为(1/4)^k
     96  * 参数含义:num代表要判定的数,k代表测试次数
     97  */
     98 bool RSA::isPrime(const BigInteger & num, const unsigned k) {
     99     assert(num != BigInteger::ZERO);// 测试num是否为0
    100     if (num == BigInteger::ONE)
    101         return false;    // 1不是素数
    102     if (num == BigInteger::TWO)
    103         return true;    // 2是素数
    104 
    105     BigInteger t = num-1;
    106     BigInteger::bit b(t);// 二进制数
    107     if (b.at(0) == 1)    // 减一之后为奇数,原数为偶数
    108         return false;
    109     // num-1 = 2^s*d
    110     size_t s = 0;    // 统计二进制末尾有几个0
    111     BigInteger d(t);
    112     for (size_t i=0; i<b.size(); ++i) {
    113         if (!b.at(i)) {
    114             ++s;
    115             d = d.shiftRight(1);// 计算出d
    116         }
    117         else
    118             break;
    119     }
    120 
    121     for (size_t i=0; i<k; ++i) {// 测试k次
    122         BigInteger a = createRandomSmaller(num);// 生成一个介于[1,num-1]之间的随机数a
    123         BigInteger x = a.modPow(d, num);
    124         if (x == BigInteger::ONE)// 可能为素数
    125             continue;
    126         bool ok = true;
    127         // 测试所有0<=j<s,a^(2^j*d) mod num != -1
    128         for (size_t j=0; j<s && ok; ++j) {
    129             if (x == t)
    130                 ok = false;    // 有一个相等,可能为素数
    131             x = x.multiply(x).mod(num);
    132         }
    133         if (ok)    // 确实都不等,一定为合数
    134             return false;
    135     }
    136     return true;    // 通过所有测试,可能为素数
    137 }
    138 
    139 /**
    140  * 函数功能:随机生成一个比val小的数
    141  * 参数含义:val代表比较的那个数
    142  */
    143 BigInteger RSA::createRandomSmaller(const BigInteger & val) {
    144     BigInteger::base_t t = 0;
    145     do {
    146         t = rand();
    147     } while (t == 0);// 随机生成非0数
    148 
    149     BigInteger mod(t);
    150     BigInteger ans = mod%val;    // 比val要小
    151     if (ans == BigInteger::ZERO)// 必须非零
    152         ans = val-BigInteger::ONE;
    153     return ans;
    154 }
    155 
    156 /**
    157  * 函数功能:生成一个二进制长度为len的大素数
    158  * 参数含义:len代表大素数的长度,k代表素数检测的次数
    159  */
    160 BigInteger RSA::createPrime(unsigned len, const unsigned k) {
    161     assert(k > 0);
    162     BigInteger ans = createOddNum(len);// 先生成一个奇数
    163     while (!isPrime(ans, k)) {// 素性检测
    164         ans = ans.add(BigInteger::TWO);// 下一个奇数
    165     }
    166     return ans;
    167 }
    168 
    169 /**
    170  * 函数功能:根据提供的欧拉数生成公钥、私钥指数
    171  * 参数含义:eul表示提供的欧拉数
    172  */
    173 void RSA::createExponent(const BigInteger & eul) {
    174     e = 65537;
    175     d = e.modInverse(eul);
    176 }
    View Code

    2.3 EncryptDecrypt类

        该类主要用于封装加解密的一些操作,比如判断数据是否合法,输入输出加解密信息等。

        该模块同样有两个文件:EncryptDecrypt.h和EncryptDecrypt.cpp。代码如下所示。

        EncryptDecrypt.h代码如下。

     1 /**
     2  * @Name    : EncryptDecrypt.h
     3  * @Date    : 2017-04-11-22.29.58
     4  * @Author  : Silenceneo (silenceneo_xw@163.com)
     5  * @Link    : http://www.cnblogs.com/Silenceneo-xw/
     6  * @Version : 2.0
     7  */
     8 
     9 #ifndef __ENCRYPTDECRYPT_H__
    10 #define __ENCRYPTDECRYPT_H__
    11 
    12 #include <string>
    13 #include "RSA.h"
    14 class EncryptDecrypt {
    15 public:
    16     EncryptDecrypt() {}
    17     ~EncryptDecrypt() {}
    18 
    19     void menu();    // 菜单显示
    20     bool encrypt();    // 加密
    21     bool decrypt();    // 解密
    22     void print();    // 打印RSA相关信息
    23     void reset();    // 重置RSA相关信息
    24 protected:
    25     void load(int);    // 根据给定位数加载RSA对象
    26     bool islegal(const std::string &);// 判断输入字符串是否合法
    27 private:
    28     RSA rsa;
    29 };
    30 
    31 #endif // __ENCRYPTDECRYPT_H__
    View Code

        EncryptDecrypt.cpp代码如下。

      1 /**
      2  * @Name    : EncryptDecrypt.cpp
      3  * @Date    : 2017-04-11-22.32.18
      4  * @Author  : Silenceneo (silenceneo_xw@163.com)
      5  * @Link    : http://www.cnblogs.com/Silenceneo-xw/
      6  * @Version : 2.0
      7  */
      8 
      9 #include <iostream>
     10 #include <ctime>
     11 #include "EncryptDecrypt.h"
     12 
     13 /**
     14  * 函数功能:菜单显示
     15  */
     16 void EncryptDecrypt::menu() {
     17     std::cout << "**********Welcome to use RSA encoder**********" << std::endl;
     18     std::cout << "               e: encrypt 加密               " << std::endl;
     19     std::cout << "               d: decrypt 解密               " << std::endl;
     20     std::cout << "               p: print   显示               " << std::endl;
     21     std::cout << "               r: reset   重置               " << std::endl;
     22     std::cout << "               q: quit    退出               " << std::endl;
     23     std::cout << "input your choice:" << std::endl;
     24 }
     25 
     26 /**
     27  * 函数功能:加密运算
     28  */
     29 bool EncryptDecrypt::encrypt() {
     30     std::string str;
     31     std::cout << "输入16进制数据:" << std::endl;
     32     std::cout << ">";
     33     std::cin >> str;// 输入明文
     34     if (!std::cin || !islegal(str))
     35         return false;
     36     BigInteger m(str);
     37     clock_t start = clock();
     38     BigInteger c = rsa.encryptByPublic(m);
     39     clock_t finish = clock();
     40 
     41     std::cout << std::fixed;
     42     std::cout.precision(3);
     43     std::cout << "用时: " << (double)(finish-start)/CLOCKS_PER_SEC << "s." << std::endl;
     44     std::cout << "明文: " << m << std::endl;
     45     std::cout << "密文: " << c << std::endl;
     46     return true;
     47 }
     48 
     49 /**
     50  * 函数功能:解密运算
     51  */
     52 bool EncryptDecrypt::decrypt() {
     53     std::string str;
     54     std::cout << "输入16进制数据:" << std::endl;
     55     std::cout << ">";
     56     std::cin >> str;// 输入密文
     57     if (!std::cin || !islegal(str))
     58         return false;
     59     BigInteger c(str);
     60     clock_t start = clock();
     61     BigInteger m = rsa.decryptByPrivate(c);
     62     clock_t finish = clock();
     63 
     64     std::cout << std::fixed;
     65     std::cout.precision(3);
     66     std::cout << "用时: " << (double)(finish-start)/CLOCKS_PER_SEC << "s." << std::endl;
     67     std::cout << "密文: " << c << std::endl;
     68     std::cout << "明文: " << m << std::endl;
     69     return true;
     70 }
     71 
     72 /**
     73  * 函数功能:输出RSA相关信息
     74  */
     75 void EncryptDecrypt::print() {
     76     std::cout << rsa << std::endl;
     77 }
     78 
     79 /**
     80  * 函数功能:重置RSA相关信息
     81  */
     82 void EncryptDecrypt::reset() {
     83     std::cout << "输入密钥长度: ";
     84     int len;
     85     std::cin >> len;
     86     load(len>>1);
     87 }
     88 
     89 /**
     90  * 函数功能:根据给定位数len加载rsa
     91  */
     92 void EncryptDecrypt::load(int len) {
     93     std::cout << "初始化..." << std::endl;
     94     clock_t start = clock();
     95     rsa.init(len);    // 初始化
     96     clock_t finish = clock();
     97     std::cout << "初始化完成." << std::endl;
     98     std::cout << std::fixed;
     99     std::cout.precision(3);
    100     std::cout << "用时: " << (double)(finish-start)/CLOCKS_PER_SEC << "s." << std::endl;
    101 }
    102 
    103 /**
    104  * 函数功能:判断输入字符串str是否合法
    105  * 参数含义:str代表输入的字符串
    106  */
    107 bool EncryptDecrypt::islegal(const std::string & str) {
    108     for (std::string::const_iterator it=str.begin(); it!=str.end(); ++it) {
    109         if (!isalnum(*it))    // 不是字母或者数字
    110             return false;
    111         if (isalpha(*it)) {
    112             char ch = tolower(*it);
    113             if (ch > 'f')    // 超过十六进制字符'f'
    114                 return false;
    115         }
    116     }
    117     return true;
    118 }
    View Code

    2.4 主文件

        该模块就只有一个文件:Main.cpp。主要用于使各个模块结合起来,执行相应操作。

        Main.cpp代码如下。

     1 /**
     2  * @Name    : Main.cpp
     3  * @Date    : 2017-04-11-22.19.24
     4  * @Author  : Silenceneo (silenceneo_xw@163.com)
     5  * @Link    : http://www.cnblogs.com/Silenceneo-xw/
     6  * @Version : 2.0
     7  */
     8 
     9 #include <iostream>
    10 #include "EncryptDecrypt.h"
    11 
    12 int main() {
    13     EncryptDecrypt encrypt_decrypt;
    14     encrypt_decrypt.reset();// 设置密钥长度
    15 
    16     char ch;
    17     std::string str;
    18     bool ok = true;
    19 
    20     do {
    21         encrypt_decrypt.menu();// 菜单显示
    22         std::cout << ">";
    23         std::cin >> str;
    24         if (str.empty()) {
    25             std::cout << "输入错误!请重新输入!" << std::endl;
    26             continue;
    27         }
    28         ch = str.at(0);
    29         switch(ch) {
    30         case 'e':
    31         case 'E':
    32             if (!encrypt_decrypt.encrypt())
    33                 std::cout << "加密失败,请重试!" << std::endl;
    34             break;
    35         case 'd':
    36         case 'D':
    37             if (!encrypt_decrypt.decrypt())
    38                 std::cout << "解密失败,请重试!" << std::endl;
    39             break;
    40         case 'p':
    41         case 'P':
    42             encrypt_decrypt.print();// 打印相关信息
    43             break;
    44         case 'r':
    45         case 'R':
    46             encrypt_decrypt.reset();// 重新设置密钥长度
    47             break;
    48         case 'q':
    49         case 'Q':
    50             ok = false;    // 退出
    51             break;
    52         default:
    53             break;
    54         }
    55     } while (ok);
    56     return 0;
    57 }
    View Code

        至此,RSA加密算法已经介绍完毕了,如有任何错误,欢迎指出,不胜感激。

    附录

    RSA加密算法 Java版本

        附上Java版本的RSA加密算法,仅供参考。

        RSA.java代码如下。

     1 import java.math.BigInteger;
     2 import java.util.Random;
     3 
     4 public class RSA {
     5     public BigInteger n, e;// 公钥
     6     private BigInteger d;// 私钥
     7     private BigInteger p, q;
     8     private BigInteger eul;// n的欧拉函数
     9     
    10     /**
    11      * 函数功能:初始化RSA对象的相关信息
    12      * 参数含义:len表示大素数的二进制位数
    13      */
    14     public void init(int len) {
    15         Random random = new Random();
    16         // 产生大素数p和q
    17         p = BigInteger.probablePrime(len, random);
    18         q = BigInteger.probablePrime(len, random);
    19         // 计算出n
    20         n = p.multiply(q);
    21         // 计算出n的欧拉函数
    22         eul = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
    23         // 设置加解密指数e和d
    24         createExponent(eul);
    25     }
    26 
    27     /**
    28      * 函数功能:使用公钥进行加密
    29      * 参数含义:m表示要加密的明文
    30      */
    31     public BigInteger encryptByPublic(BigInteger m) {
    32         return m.modPow(e, n);
    33     }
    34     
    35     /**
    36      * 函数功能:使用私钥进行解密
    37      * 参数含义:c表示要解密的密文
    38      */
    39     public BigInteger decryptByPrivate(BigInteger c) {
    40         return c.modPow(d, n);
    41     }
    42 
    43     // 以下主要用于数字签名
    44     /**
    45      * 函数功能:使用私钥进行加密
    46      * 参数含义:m表示要加密的明文
    47      */
    48     public BigInteger encryptByPrivate(BigInteger m) {
    49         return decryptByPrivate(m);
    50     }
    51     
    52     /**
    53      * 函数功能:使用公钥进行解密
    54      * 参数含义:c表示要解密的密文
    55      */
    56     public BigInteger decryptByPublic(BigInteger c) {
    57         return encryptByPublic(c);
    58     }
    59     
    60     /**
    61      * 函数功能:从一个欧拉数中生成公钥、私钥指数
    62      * 参数含义:eul表示提供的欧拉数
    63      */
    64     private void createExponent(BigInteger eul) {
    65         // TODO Auto-generated method stub
    66         e = new BigInteger("65537");
    67         d = e.modInverse(eul);
    68     }
    69     
    70     /**
    71      * 函数功能:输出RSA相关数据
    72      */
    73     public void print() {
    74         System.out.println("n: " + n);
    75         System.out.println("p: " + p);
    76         System.out.println("q: " + q);
    77         System.out.println("e: " + e);
    78         System.out.println("d: " + d);
    79     }
    80 }
    View Code

        EncryptDecrypt.java代码如下。

      1 import java.math.BigInteger;
      2 import java.util.Scanner;
      3 
      4 public class EncryptDecrypt {
      5     private RSA rsa = new RSA();
      6     public Scanner in = new Scanner(System.in);
      7     
      8     /**
      9      * 函数功能:菜单显示
     10      */
     11     public void menu() {
     12         System.out.println("**********Welcome to use RSA encoder**********");
     13         System.out.println("               e: encrypt 加密               ");
     14         System.out.println("               d: decrypt 解密               ");
     15         System.out.println("               p: print   显示               ");
     16         System.out.println("               r: reset   重置               ");
     17         System.out.println("               q: quit    退出               ");
     18         System.out.println("input your choice:");
     19     }
     20     
     21     /**
     22      * 函数功能:加密运算
     23      */
     24     public boolean encrypt() {
     25         System.out.println("输入10进制数据:");
     26         System.out.print(">");
     27         String str = in.next();
     28         if (str==null || str.isEmpty() || !islegal(str))
     29             return false;
     30         BigInteger m = new BigInteger(str);
     31         long start = System.currentTimeMillis();
     32         BigInteger c = rsa.encryptByPublic(m);
     33         long finish = System.currentTimeMillis();
     34         System.out.println("用时:" + (finish-start) + "ms.");
     35         System.out.println("明文: " + m);
     36         System.out.println("密文: " + c);
     37         return true;
     38     }
     39     
     40     /**
     41      * 函数功能:解密运算
     42      */
     43     public boolean decrypt() {
     44         System.out.println("输入10进制数据:");
     45         System.out.print(">");
     46         String str = in.next();
     47         if (str==null || str.isEmpty() || !islegal(str))
     48             return false;
     49         BigInteger c = new BigInteger(str);
     50         long start = System.currentTimeMillis();
     51         BigInteger m = rsa.decryptByPrivate(c);
     52         long finish = System.currentTimeMillis();
     53         System.out.println("用时:" + (finish-start) + "ms.");
     54         System.out.println("密文: " + c);
     55         System.out.println("明文: " + m);
     56         return true;
     57     }
     58     
     59     /**
     60      * 函数功能:输出RSA相关信息
     61      */
     62     public void print() {
     63         rsa.print();
     64     }
     65     
     66     /**
     67      * 函数功能:重置RSA相关信息
     68      */
     69     public void reset() {
     70         System.out.print("输入密钥长度: ");
     71         int len = in.nextInt();
     72         load(len>>1);
     73     }
     74 
     75     /**
     76      * 函数功能:根据给定位数len加载rsa
     77      */
     78     private void load(int len) {
     79         // TODO Auto-generated method stub
     80         System.out.println("初始化...");
     81         long start = System.currentTimeMillis();
     82         rsa.init(len);
     83         long finish = System.currentTimeMillis();
     84         System.out.println("初始化完成.");
     85         System.out.println("用时:" + (finish-start) + "ms.");
     86     }
     87 
     88     /**
     89      * 函数功能:判断输入字符串str是否合法
     90      * 参数含义:str代表输入的字符串
     91      */
     92     private boolean islegal(String str) {
     93         // TODO Auto-generated method stub
     94         for (int i = 0; i < str.length(); i++) {
     95             char ch = str.charAt(i);
     96             if (!Character.isDigit(ch)) {
     97                 return false;
     98             }
     99         }
    100         return true;
    101     }
    102 }
    View Code

        Main.java代码如下。

     1 public class Main {
     2 
     3     public static void main(String[] args) {
     4         // TODO Auto-generated method stub
     5         EncryptDecrypt encryptDecrypt = new EncryptDecrypt();
     6         encryptDecrypt.reset();
     7 
     8         do {
     9             encryptDecrypt.menu();
    10             System.out.print(">");
    11             String str = encryptDecrypt.in.next();
    12             if (str==null || str.isEmpty()) {
    13                 System.out.println("输入错误,请重新输入!");
    14                 continue;
    15             }
    16             char ch = str.charAt(0);
    17             switch(ch) {
    18             case 'e':
    19             case 'E':
    20                 if (!encryptDecrypt.encrypt()) {
    21                     System.out.println("加密失败,请重试!");
    22                 }
    23                 break;
    24             case 'd':
    25             case 'D':
    26                 if (!encryptDecrypt.decrypt()) {
    27                     System.out.println("解密失败,请重试!");
    28                 }
    29                 break;
    30             case 'p':
    31             case 'P':
    32                 encryptDecrypt.print();
    33                 break;
    34             case 'r':
    35             case 'R':
    36                 encryptDecrypt.reset();
    37                 break;
    38             case 'q':
    39             case 'Q':
    40                 encryptDecrypt.in.close();
    41                 System.exit(0);
    42                 break;
    43             default:
    44                 break;
    45             }
    46         } while (true);
    47     }
    48 
    49 }
    View Code
    本文为博主原创文章,转载请注明出处:http://www.cnblogs.com/Silenceneo-xw/
  • 相关阅读:
    纯CSS实现自动轮播,CSS变量的定义与使用,计算属性的使用
    input:file样式怎样修改
    Div转为Canvas简直不要太好玩~~~
    oracle nvl2函数
    oracle 子查询
    oracle 分组函数执行分析
    oracle外部表
    oracle USING 用法
    面向对象进阶
    面向对象基础
  • 原文地址:https://www.cnblogs.com/Silenceneo-xw/p/6718334.html
Copyright © 2011-2022 走看看