[摘要] 大数运算不仅仅运用在密码学中,还运用在一些物理学研究、生物学,化学等科目中。大数运算,意味着参加的值和计算结果通常是以上百位数,上千位数以及更大长度之间的整数运算。例如大家所熟知圆周率π的值,在一般的数值计算中用到圆周率的不须要多大的精度,但在计算一些星球或是星系上的体积面积时便显的误差很大了,这就要求π值计算的精度达到几百万位甚至更高,才能缩小误差。人工计算是远远不行了,而且本身误差也无法估计。只有在计算机中用大数运算求π值了。又如,考古学家计算石头内的碳元素衰变来考证地球形成的时间,更是将计算的结果精确到了百年以内。所以说大数的运算是涉及领域多,应用范广,与我们生活息息关。在此,我采用一个在C语言下实现计算大数运算的一个程序为例,讲解包括了大数的加法,减法,乘法和除法及求幂运算的算法及代码。
[关键词] 大数计算 网络安全 密码学
随着计算机网络技术的发展和因特网的广泛普及,网络安全事故逐年增加,黑客的攻击已经和病毒并列成为对信息安全影响最严重的两大危害。其很大程度上是被黑客破解了用户的计算机名及登陆密码及资料的加密较差,而使得黑客来对网民的资料如同自己般的随意更改和破坏。而安全的密码和账号成为了网民的安全之本,怎么才能提高安全问题成为的人们和社会关注的问题。而加密大部又是以大素数的计算为基础的,如非对称密码体制RSA的安全性依赖于对大数进行因数分解的耗时性。一个二进制数n的因数分解所需的机器周期大约是exp{[ln(n)ln(ln(n))]1/2}。若机器周期为1μs,b为二进制数的位数,分解 n=2b 所需时间如下表所示:
位数 | 100 | 200 | 300 | 500 | 750 | 1000 |
时间 | 30秒 | 3天 | 9年 | 1兆年 | 2*109年 | 6*1015年 |
1. 数字存储的实现
大数计算的因数和结果精度一般是少则数十位,多则几万位。在C语言中定义的类型中精度最多只有二十多位,因而我们采取用链表存贮的方式来存放大数。在计算中会用到从高位开始计算,和从低位开始计算数值的两种情况。所以我们将链表定义为双向链表,其中为一个单元来存贮数据,一个指针指向前方的数据,另一个指向后的数据。其结构为:
struct Node // 定义一个双向链表用来存贮结果 { char data; // 数据*定义为字符的原因:要显示负号 Node *next; // 尾指针 Node *ahead; // 首指针 }; |
2.1 加法运算的实现
加法计算还是比较容易的,我们也是先从低位算起,因为只须要对应的位相加,再加上前一位的进位,再去判断是否本位是否有进位, 有则把本位数字改为减去它的权,也就是10,再置进位为1。如果没有进位,则给进位赋值0。
![](http://ces.ustc.edu.cn/jpg/pap/wh/i02.gif)
1、两个加数中那一个数的位数长,以位数长的作为循环变量;
2、结束循环时,不仅仅是最后一位加完就停止,还应加入如果有进位,也要再循环一次。如最后一位是9,进位是1,则相加时进位,要加上进位这一位值。具体看代码,输入输出时和乘法的一样。
/*-------------------------------------------------------------------------- *函数名称: 大数加法 *函数过程:1 比较两个数那一个长 * 2 以长的作为循环次数 * 3 对应项相加 进位存贮直到下高位相加用 * 4 直到循环结束 * 5 !!!!!!没设计负数相加 *入口参数:numa,numb,result字符串 *出口参数:无 *编辑环境:winSP2 + VC2003 + C++ *--------------------------------------------------------------------------*/ void addition(char *numa, char *numb,char *result) // 计算两大数之和 { char *pna = findend(numa); // 指向numa的一个指针。point numa pna 指向乘数的最低位, char *pnb = findend(numb); |