数学研发论坛

 找回密码
 欢迎注册

Baillie_PSW素性判定的代码

已有 368 次阅读2019-2-27 14:31

Clear["Global`*"];(*Clear all variables*)
Lucas[n0_]:=Module[
    (*指定局部变量*)
    {n=n0,m,s,P,Q,d,JS,mi2,UU,VV,uutemp,vvtemp,Utemp,Vtemp,kk},
    If[Mod[n,2]==0&&n>2,Return[False]];(*排除偶数*)
    If[IntegerQ[Sqrt[n]],Return[False]];(*如果是完全平方数,返回False*)
    (*写成n+1=2^s*m的形式*)
    m=n+1;
    (*s=0;While[Mod[m,2]==0,m=m/2;s=s+1];*)
    (*根据P=3 4 5 6 7 Q=1,以及雅克比符号等于-1来找到P,如果d与n有约数,则返回false,且d不应该是n的倍数*)
    (*此处如果n很小,而d较大且是n的倍数,这时可能存在n是质数,而雅克比符号等于零的情况,这种情况需要特殊处理一下*)
    P=3;Q=1;d=P^2-4*Q;JS=JacobiSymbol[d,n];If[JS==0,Return[False]];
    While[JS==1,P=P+1;d=P^2-4*Q;JS=JacobiSymbol[d,n];If[JS==0,Return[False]]];
    mi2=IntegerDigits[m,2];(*把m写成二进制的方式*)
    UU=1;VV=P;(*分别是lucas序列的U(1)与V(1)的值*)
    Do[
        Utemp=Mod[UU*VV,n];
        Vtemp=Mod[VV^2-2,n];(*此处Q=1*)
        If[mi2[[kk]]==1,
            uutemp=(P*Utemp+Vtemp);
            vvtemp=(d*Utemp+P*Vtemp);
            (*uutemp,vvtemp都可能是奇数,如果是奇数,则加上一个n,这样就是偶数了,
            下面才能除以2得到整数,至于为什么要这么做,我也不是太清楚为什么,
            可能是由于n是奇数,模的时候,减去偶数个n奇偶性不变,而减去奇数个n奇偶性变了*)
            If[OddQ[uutemp],uutemp=uutemp+n];
            If[OddQ[vvtemp],vvtemp=vvtemp+n];
            UU=Mod[uutemp/2,n];
            VV=Mod[vvtemp/2,n],
            UU=Utemp;
            VV=Vtemp
        ],
        {kk,2,Length@mi2}];(*此处必须从2开始,程序没有错误!*)
    If[UU==0&&Mod[VV,n]==2,Return[True],Return[False]]
]

(*miller rabin测试,n0是被测试的整数,a0是选择的基*)
MillerRabin[n0_,a0_]:=Module[{n=n0,a=a0,s,m,t1,k},
    s=0;m=n-1;While[Mod[m,2]==0,m=m/2;s=s+1];
    t1=PowerMod[a,m,n];
    If[t1==1,Return[True]];
    k=0;While[k<s-1&&t1!=n-1,k=k+1;t1=Mod[t1^2,n]];
    If[t1==n-1,Return[True],Return[False]]
]


路过

雷人

握手

鲜花

鸡蛋

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 欢迎注册

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2019-11-16 09:22 , Processed in 0.027459 second(s), 15 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

返回顶部