第一章 :数值算法

本文介绍了计算机算法中涉及数学运算的基础知识,包括模运算、素数分解、最大公约数求解、费马小定理及RSA加密算法。通过欧几里德准则、扩展欧几里德算法等手段解决了素数判断与最大公约数问题,进一步阐述了模运算在RSA加密中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     因为最开始的计算机算法都是为了解决数学问题,因此我们首先介绍一些很基本的涉及数学运算的算法,其中会涉及一些初等数论知识。这一章的核心可以归结为以下两个问题,1.求一个数的素数分解 2.判断一个数是否是素数。

模运算:

     基本的四则运算相信大家都应该比较熟悉,就不再赘述。这里主要用到的是整数的模运算,这是数论里最基本的一个运算,有很多的应用场景,本章提到的算法也都和模运算有关。如下:

 

     定义: 设 x,N   均为整数,若x=q*N+r,其中0<=r<N,q和r均为整数,则r称为x对N的模,简写为x mod N 。

     如果x mod N==y mod N,我们简写成x==y(mod N),接下来我们考虑在模运算下的基本运算法则,首先引入模运算的一个基本定理:

   

     替换准则:

           如果x==x(mod N),y==y'(mod N),则x+y==x'+y'(mod N), xy==x'y'(mod N)

 

     有了上述准则,我们可以很方便的进行大数的求模运算,如下

            2345==(25)69==3269==169==1 (mod 31)

     考虑对xmod N,在x,y,N都很大的情况下,运算量非常大,考虑常规的计算顺序:

         x mod N --> x2 mod N -->x3 mod N -->...... --> xy mod N ,

     如果y有500 bits,那么上述计算总共需要2500次乘法运算。我们可以用一种更聪明的计算序列,

         x mod N --> x2 mod N -->x4 mod N -->x8 mod N -->...... --> xy mod N ,

     这样,只需要进行500次乘法运算即可求出结果。      

 

    但是上述准则只给出了在模运算下进行加法和乘法的运算法则,那减法和除法呢,首先考虑减法,其实和普通的四则运算一样,减去一个数相当于加上这个数的相反数,这样减法即可用加法来表示,如下:

     5==25(mod 10),14==4(mod 10) ,

     则5-14(mod 10)==-9(mod 10)==1(mod 10)==21(mod 10)

                                ==25-4(mod 10) 

    值得注意的是,虽然加减法和乘法在模运算下都成立,但是除法在模运算下并不成立。

 

     既然有了模运算这个工具 ,那肯定得给它找点用武之地了,接下来我们开始用这个工具解决几个问题,最著名的可能就是求两个整数的最大公约数(gcd)了:

 

     欧几里德准则:

         如果x和y 均是正整数并且x>=y,那么gcd(x,y)==gcd(y,x mod y)。

 

     为什么呢,可以想一下,如果r是上述准则中x和y的最大公约数,那么x==ar,y=br,则x-y=(a-b)r,可作简单推倒如下:

             gcd(x,y)=gcd(x-y,y)=gcd(x-2y,y)....... =gcd(x mod y,y)=gcd(y,x mod y);

     有了上述准则,算法岂不是很容易了,为了简单,没有考虑负数等情况,只考虑最简单的a>=b>=0的情况,算法如下:

     int gcd(int a,int b)

     {

         if(b==0) return a;

         else        ruturn gcd(b,a %b);

     }

      求出了最大公约数,我们在给出一个相关的定理,

 

      如果d是a和b的公约数,并且对某个整数x和y满足d=ax+by,

      那么d==gcd(a,b)

            简单证明: gcd(a,b)是a,b的最大公约数 => gcd(a,b)>=d(1)

                            gcd(a,b)整除a和b  =>  

                            gcd(a,b)整除ax+by=d  =>

                            gcd(a,b)<=d  (2)

                            由(1)(2)可知,gcd(a,b)==d

       那我们怎么才能把x和y求出来呢,很简单,我们对上述gcd算法进行一下扩展,由于要返回三个值,为书写方便,采用如下伪代码:

     

       function extended-gcd( a ,b)     //a,b均为正整数且a>b

       {

           if b==0) return (1,0,a);

           (x,y,d)=extended-gcd(b,a mod b);

            return (y,x - floor(a/b)*y,d);  //floor 函数表示向下取整

        }

 

        上述是一个递归算法,基本情况是b==0时,此时gcd(a,b)=a*1+b*0;

    若b不为0,则假设已求出extended-gcd(b,a mod b),   此时,

    gcd(a,b) =gcd(b,a mod b)

                  =x*b +y *(a mod b)

                  =x*b+y*(a-floor(a/b)*b)=y*a+(x-floor(a/b)*y)*b.

 

  接下来,对文章开始提出的第二个问题进行解答,即能否判断一个数是否是素数。首先引入一个相关的定理:

  

  费马小定理: 如果p是素数,那么对任意的1<=a<p, 有 ap-1 ==1 (mod p)

  

  上述定理给出了p为素数的一个必要条件,对于任意给定的数,我们可以根据上述定理证明它不是素数,但似乎无法证明它是素数,那怎么办呢,给出的解决方案很简单,多试几次,如果连着n次都符合素数的条件,那就可以以近似1的概率认为这个数是素数,n值一般取10左右即可,理论上,这种判断方法有可能会判断错误,但是这是小概率事件,可以认为不会发生,具体算法:

   function primality(N)

   Input: positive integer N

   Output: yes/no

   pick  positive integers a1,a2,...ak<N at random

   if aiN-1==1(mod N) for all i=1,2......k

        return yes

   else

        return no

 

   至于第一个问题,数学家们已经研究很久很久,不过至今没有什么有效的算法能够快速求解,当然,没法解这个问题不代表它没有意义,正因为这个问题在现有的计算机上无法求解,这反而给大家提供了一种保证信息安全的机制,我们接下来探讨一下著名的RSA加密算法,这也算是模运算和素数理论的一个重大贡献了。

   为了解释这个算法,我们还需要了解一个概念,即对模运算,我们引入一个乘法‘逆’的概念:

 

    定义:如果ax==1(mod N),那么我们把x称为a在模N运算下的乘法逆。

    定理:对任意的a和N,a在模N运算下的乘法逆存在,当且仅当N和a互素,即gcd(a,N)==1

    

     可以证明,如果一个数在模运算下的乘法逆存在,则它是唯一的。 例如,3*7(mod 10)==1,所以3是7在模10运算下的逆,那引入这 个‘逆’的概念有什么用呢,最直接的就是在RSA算法中的加解密运算了。我们来分析一下加解密的原理,

设原始数据是x,任意找两个素数p和q,设N=p*q,M=(p-1)*(q-1)),再任意找一个数e,满足gcd(e,M)==1,这样,根据上述定理,在模M运算下e的逆s必存在。我们用e对原始数据进行加密,y=encode(x)=xe(mod N),用s对收到的y进行解密,decode(y)=yd(mod N)=xed(mod N),接下来我们证明decode(y)==x (mod N) :

      由于ed==1(mod M),即ed=1+k(p-1)*(q-1),其中k为某整数。

                         则有xed-x     (mod p)

                                =x 1+k(p-1)*(q-1) - x (mod p)

                                =x*(x k(p-1)*(q-1) - 1) (mod p)

                                =0 (费马小定理)

  所以xed-x 是p的倍数,同理可知,xed-x 是q的倍数

  又因为p和q均是素数,所以xed-x 是N=p*q的倍数。

  所以xed-x =0(mod N),即xed=x (mod N),这相当于解密出来原始数据。

   RSA是一种公钥加密技术,什么意思呢,就是说,公钥是用来加密的,每个人都可以看见,私钥用来解密,只有我一个人可以看到,这样,如果有人给你发送消息,就用你的公钥进行加密,你可以用私钥对收到的密文进行解密,其他人也可以收到密文,但是由于没有私钥,强行破解算法是一个当前计算机无法解决的复杂度,这也就相当于保证了信息的安全。相信大家已经看出来了,上述证明中的e即是公钥,而d则是私钥,当然两者的角色也是可以互换的。

   下面用Alice和Bob之间的通信说明RSA的工作过程:

   Bob:接收方

        1 随机挑选两个很大的素数(n-bit)p和q

        2 他的公钥是(N,e),其中N=pq,e是一个和(p-1)(q-1)互素的数(2n-bit)

        3 他的私钥是d,其中d是e在模(p-1)(q-1)运算下的乘法逆

        5 收到密文y后,可通过yd mod N计算原始信息x

   Alice:发送方

         4 设发送的原始数据为x,首先找到Bob的公钥(N,e),加密y=(xe mod N)

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值