基础数论——算数基本定理、欧几里得算法、丢番图方程

整除

【定义】 对于 a , b ∈ Z a,b \in Z a,bZ,如果有 q ∈ Z q \in Z qZ使得 a q = b aq=b aq=b,则称 a a a整除 b b b,记为 a ∣ b a|b ab.

关于整除有如下结论:

  • c = k 1 a + k 2 b c=k_1a+k_2b c=k1a+k2b e ∣ a e|a ea,且 e ∣ b e|b eb,则 e ∣ c e|c ec.
最大公因子

【定义】 所有同时整除 a a a b b b的整数中,最大的那个,称为 a a a b b b的最大公因子,记为
( a , b ) (a,b) (a,b),也可记为 g c d ( a , b ) gcd(a,b) gcd(a,b).

【引理】 设 a = b q + c a=bq+c a=bq+c,这里 a , b , c , q ∈ Z a,b,c,q\in Z a,b,c,qZ,则 ( a , b ) = ( b , c ) (a,b)=(b,c) (a,b)=(b,c).

证明:由于 a = b q + c a=bq+c a=bq+c,所有 b b b c c c的公因子同时整除 b b b c c c ,所以也能整除 a a a,所以也是 a a a b b b的公因子。由于 c = a − b q c=a-bq c=abq,所有 a a a b b b的公因子同时整除 a a a b b b ,所以也能整除 c c c,所以也是 b b b c c c的公因子。也就是说, a a a b b b的公因子, b b b c c c的公因子是同一拨,那么 a a a b b b的公因子中最大的那个, b b b c c c的公因子中最大的那个
当然是同一个了。
所以 ( a , b ) = ( b , c ) (a,b)=(b,c) (a,b)=(b,c)

欧几里得算法

欧几里德算法又称辗转相除法,是指用于计算两个正整数 a a a b b b的最大公因子。证明过程主要依据上面的引理 ( a , b ) = ( b , c ) (a,b)=(b,c) (a,b)=(b,c)

代码实现如下:

#include
#include

/*
欧几里德算法:辗转求余
原理: gcd(a,b)=gcd(b,a mod b)
当b为0时,两数的最大公约数即为a
*/
int gcd(int a, int b){
    if (a < b){
        std::swap(a, b);
    }
    if (0 == b){
        return a;
    }else{
        return gcd(b, a % b);
    }
}

// 简单测试
int main() {
    int t = gcd(10,25);
    std::cout<
扩展欧几里得算法

【定义】 对于 a 1 , ⋯   , a n ∈ Z a_1,\cdots,a_n\in Z a1,,anZ,我们称 a 1 x 1 + ⋯ + a n x n ( x 1 , ⋯   , x n ∈ Z ) a_1x_1+ \cdots + a_nx_n(x_1,\cdots,x_n\in Z) a1x1++anxn(x1,,xnZ) a 1 , ⋯   , a n a_1,\cdots,a_n a1,,an的整系数线性组合,并用 a 1 Z + ⋯ + a n Z a_1Z+\cdots+a_nZ a1Z++anZ表示它们构成的集合。

【扩展欧几里得算法】 设 a a a b b b是两个正整数(至少有一个非零), d = g c d ( a , b ) d=gcd(a,b) d=gcd(a,b),则存在整数 x x x y y y使得 a x + b y = d ax+by=d ax+by=d成立,如果 a a a b b b都是素数,那么存在整数 x x x y y y使得 a x + b y = 1 ax+by=1 ax+by=1成立。

代码实现:

def egcd(a,b):
    if 0 == b:
        return a,1,0
    gcd,k1,k2 = egcd(b, a%b)
    return gcd,k2,k1-a/b*k2
互素

最大公因子的最小可能取值是 1 1 1,当 ( a , b ) = 1 (a,b)=1 (a,b)=1 a a a b b b的最大公因子为 1 1 1时,我们称 a a a b b b互素。

乘法逆元

( a , b ) = 1 (a,b)=1 (a,b)=1时,有时候我们很希望求得一个数 k k k 0 ≤ k < b 0\leq k \lt b 0k<b,使 k a   m o d   b = 1 ka\ mod\ b=1 ka mod b=1 ,这样的数我们称为 a a a的乘法逆元
这看起来就像是在 0 0 0 b − 1 b-1 b1这些整数中找到 a a a的倒数一样。那怎么找到这样的数呢?

扩展欧几里得算法可以帮我们解决这个问题。

由于 ( a , b ) = 1 (a,b)=1 (a,b)=1,根据扩展欧几里得算法,可求得两个系数 k 1 k_1 k1 k 2 k_2 k2,使得 k 1 a + k 2 b = ( a , b ) = 1 k_1a+k_2b=(a,b)=1 k1a+k2b=(a,b)=1,所以有 k 1 a = − k 2 b + 1 k_1a=-k_2b+1 k1a=k2b+1,所以 k 1 a   m o d   b = 1 k_1a\ mod\ b=1 k1a mod b=1 ,所以 ( k 1   m o d   b ) a   m o d   b = 1 (k_1\ mod\ b)a\ mod\ b=1 (k1 mod b)a mod b=1,而 0 ≤ ( k 1   m o d   b ) < b 0\leq(k_1\ mod\ b)\lt b 0(k1 mod b)<b,所以 ( k 1   m o d   b ) (k_1\ mod\ b) (k1 mod b)就是我们想要的那个乘法逆元。

算数基本定理

【算数基本定理(整数的唯一分解定理)】任何大于 1 1 1的整数 n n n可表示成有限个(可重复)素数的乘积,而且不计乘积中因子顺序时分解还是唯一的。

根据算数基本定理,大于 1 1 1的整数 n n n唯一地表示成 p 1 a 1 ⋅ ⋯ ⋅ p r a r p_1^{a_1}\cdot \cdots \cdot p_r^{a_r} p1a1prar的形式,这里 p 1 < ⋯ < p r p_1<\cdots<p_r p1<<pr为不同素数, a 1 , ⋯   , a r ∈ Z + a_1,\cdots,a_r\in{Z^{+}} a1,,arZ+,我们称这样的形式为 n n n的标准(素数)分解式。

欧拉函数

对任意一个正整数 n n n,在 1 1 1 n n n的这 个整数里,显然有些和 n n n是互素的,而有些和 n n n是不互素的,那些和 n n n互素的整数
的数量就是 n n n的欧拉函数,记作 ϕ ( n ) \phi(n) ϕ(n)

那么 ϕ ( n ) \phi(n) ϕ(n)该怎么计算呢?

我们都知道任意整数 n n n都可以表示成它的所有素因子的乘积:
(1) n = p 1 l 1 p 2 l 2 ⋯ p s l s n=p_1^{l_1}p_2^{l_2}\cdots p_s^{l_s}\tag{1} n=p1l1p2l2psls(1)

所以所有那些和 n n n不互素的数,一定和 n n n有其中某个素因子作为公共因子。所以我们只要从 1 1 1 n n n中的所有整数中,是 p 1 , p 2 , ⋯   , p s p_1,p_2,\cdots,p_s p1,p2,,ps的倍数的依次剔除,剩下的就是与 n n n互素的数。

例如, p 1 p_1 p1的倍数一共有多少个呢,由于 p 1 p_1 p1 的倍数在 1 1 1 n n n 中是均匀分布的,所以占据的比例是 1 p 1 \frac{1}{p_1} p11,剔除 p 1 p_1 p1的倍数后,
还剩下 n ( 1 − 1 p 1 ) n(1-\frac{1}{p_1}) n(1p11)个;在剩下的数中,由于 p 2 p_2 p2的倍数在 1 1 1 n n n中也是均匀分布的,所以占据的比例是 1 p 1 \frac{1}{p_1} p11,所以再剔除
p 2 p_2 p2的倍数后,剩下 n ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) n(1-\frac{1}{p_1})(1-\frac{1}{p_2}) n(1p11)(1p21)个。以此类推,当把所有素因子的整数倍都剔除后,剩下的数共有 n ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) ⋯ ( 1 − 1 p s ) n(1-\frac{1}{p_1})(1-\frac{1}{p_2})\cdots (1-\frac{1}{p_s}) n(1p11)(1p21)(1ps1)个。即: (2) ϕ ( n ) = n ∏ i = 1 s ( 1 − 1 p s ) \phi(n)=n\prod_{i=1}^{s}(1-\frac{1}{p_s})\tag{2} ϕ(n)=ni=1s(1ps1)(2).
由此可见,求欧拉函数的关键在于求出 n n n的所有素因子,即对 n n n做素因子分解。

有一种特殊情况, n n n为素数,那么 n n n 仅有一个素因子,即它自己。此时 ϕ ( n ) = n ( 1 − 1 n ) = n − 1 \phi(n)=n(1-\frac{1}{n})=n-1 ϕ(n)=n(1n1)=n1

还有一种特殊情况, n n n仅有两个素因子,即 n = p q n=pq n=pq,那么 ϕ ( n ) = p q ( 1 − 1 p ) ( 1 − 1 q ) = ( p − 1 ) ( q − 1 ) \phi(n)=pq(1-\frac{1}{p})(1-\frac{1}{q})=(p-1)(q-1) ϕ(n)=pq(1p1)(1q1)=(p1)(q1) 。如果已知 p p p q q q,显然 ϕ ( n ) \phi(n) ϕ(n)是好求的;而如果仅知道 n n n,而不知道 p p p q q q,那么必须要先对 n n n做素因子分解,得到 p p p q q q,才能求得 ϕ ( n ) \phi(n) ϕ(n)

如果这两个素因子 p , q p,q p,q都极大,那么当然 n n n也就极大。要从 1 1 1 n n n n n n个数中找出这两个素因子,就如同大海捞针,复杂度极高。

丢番图方程

古希腊数学家丢番图首次系统地研究了方程的整数解问题,现在涉及整数解的方程都叫做丢番图方程,也叫不定方程。

丢番图方程,又称不定方程,是未知数只能使用整数的整数系数多项式等式;即形式如 a 1 x 1 b 1 + a 2 x 2 b 2 + ⋯ + a n x n b n = c a_1x_1^{b_1} + a_2x_2^{b_2}+\cdots +a_nx_n^{b_n}=c a1x1b1+a2x2b2++anxnbn=c的等式,并且其中所有的 a j a_j aj, b j b_j bj c c c均是整数。若其中能找到一组整数解 m 1 m_1 m1, m 2 ⋯ m n m_2\cdots m_n m2mn者则称之为有整数解。线性丢番图方程为线性整数系数多项式等式,即此多项式为次数为 0 0 0 1 1 1的单项式的和。

【定理】设 a 1 , ⋯   , a n , b ∈ Z a_1,\cdots,a_n,b\in Z a1,,an,bZ,则线性丢番图方程 a 1 x 1 + a 2 x 2 + ⋯ + a n x n = b a_1x_1+a_2x_2+\cdots+a_nx_n=b a1x1+a2x2++anxn=b有整数解当且仅当 ( a 1 , ⋯   , a n ) ∣ b (a_1,\cdots,a_n)|b (a1,,an)b.

贝祖等式

对任何整數 a , b a,b a,b m m m,关于未知数 x x x y y y的线性丢番图方程(称为贝祖等式): a x + b y = m ax+by=m ax+by=m.有整数解时当且仅当 m m m a a a b b b的最大公约数 d d d的倍数,即 ( a , b ) ∣ m (a,b)|m (a,b)m.

你可能感兴趣的:(密码学)