随机素数测试 Miller Rabin 质因数分解 pollard_rho Java版 模板

来源:互联网 发布:写长篇小说的软件 编辑:程序博客网 时间:2024/05/22 06:25
import java.math.BigInteger;import java.util.HashMap;import java.util.Map;import java.util.Random;import java.util.Scanner;/** *  * @author qin * Miller_Rabin 随机素数测试 java版 * pollard_rho 质因数分解 */public class Main {//****************************************************************// Miller_Rabin 算法进行素数测试//速度快,而且可以判断 <2^63的数//****************************************************************static int S = 10;//随机算法判定次数,S越大,判错概率越小static Random rand = new Random();static BigInteger one = BigInteger.ONE;static BigInteger zero = BigInteger.ZERO;static BigInteger two = one.add(one);static BigInteger neone = zero.subtract(one);/*//计算 (a*b)%c.   a,b都是long long的数,直接相乘可能溢出的static BigInteger mult_mod(BigInteger a,BigInteger b,BigInteger c){BigInteger res = BigInteger.ZERO;a = a.mod(c);b = b.mod(c);BigInteger temp = new BigInteger("2");while( !b.equals(BigInteger.ZERO ) ){if(b.mod(temp).equals(BigInteger.ONE)) {res = res.add(a);res = res.mod(c);}a = a.shiftLeft(1);if( a.compareTo(c) >= 0) a = a.mod(c);b = b.shiftRight(1);}return res;}*///计算  x^n %cstatic BigInteger pow_mod(BigInteger x,BigInteger n, BigInteger c){if( n.equals(one) ) return x.mod(c);x = x.mod(c);BigInteger tmp = x;BigInteger ret = one;while( !n.equals(zero) ) {if( n.mod(two).equals(one) ) ret = ret.multiply(tmp).mod(c);tmp = tmp.multiply(tmp).mod(c);n = n.shiftRight(1);}return ret;}//以a为基,n-1=x*2^t      a^(n-1)=1 (mod n)  验证n是不是合数//一定是合数返回true,不一定返回falsestatic boolean check(BigInteger a,BigInteger n,BigInteger x,long t){BigInteger ret = pow_mod(a,x,n);BigInteger last = ret;for(int i=1;i<=t;i++){//ret = mult_mod(ret,ret,n);ret = ret.multiply(ret).mod(n);if( ret.equals(one) && !last.equals(one) && !last.equals(n.subtract(one))) return true;last = ret;}if( !ret.equals(one) ) return true;return false;}// Miller_Rabin()算法素数判定//是素数返回true.(可能是伪素数,但概率极小)//合数返回false;static boolean Miller_Rabin(BigInteger n){// n<2if( n.compareTo(two) == -1 ) return false;// n == 2if( n.compareTo(two) == 0 ) return true;// n&1 == 0if( n.and(one).equals(zero) ) return false;BigInteger x = n.subtract(one);long t = 1;while( x.and(one).equals(zero) ) {x = x.divide(two);//System.err.println(x);t++;}for(int i=0;i<S;i++){BigInteger a = BigInteger.valueOf(rand.nextLong());a = a.mod(n.subtract(one)).add(one);if( check(a,n,x,t) ) return false;}return true;}//************************************************//pollard_rho 算法进行质因数分解//************************************************static Map<BigInteger,BigInteger> factor = new HashMap<BigInteger,BigInteger>();static BigInteger gcd(BigInteger a, BigInteger b){if( a.equals(zero) ) return one;if( a.compareTo(zero) == -1) return gcd(a.multiply(neone),b);BigInteger t;while( !b.equals(zero) ){t = a.mod(b);a = b;b = t;}return a;}static BigInteger Pollard_rho(BigInteger x, BigInteger c){BigInteger i = one;BigInteger k = two;BigInteger x0 = new BigInteger(new Random().nextInt() + "");x0 = x0.mod(x);BigInteger y = x0,d;while( true ){i = i.add(one);//x0 = mult_mod(x0,x0,x).add(c).mod(x);x0 = x0.multiply(x0).add(c).mod(x);d = gcd(y.subtract(x0),x);if( !d.equals(one) && !d.equals(x) ) return d;if( y.equals(x0) ) return x;if( i.equals(k) ) {y = x0;k = k.add(k);}}}static void findfac(BigInteger n){if( Miller_Rabin(n) ) {BigInteger t;if( !factor.containsKey(n) ) t = one;else t = factor.get(n).add(one);factor.put(n, t);return;}BigInteger p = n, temp;int i = 0;while( p.compareTo(n) >= 0 ) {temp = BigInteger.valueOf(rand.nextLong());i = (i+1)%10;p = Pollard_rho(p,temp.mod(n.subtract(one)).add(one));}findfac(p);findfac(n.divide(p));}public static void main(String args[]){BigInteger t;Scanner cin = new Scanner(System.in);t = cin.nextBigInteger();factor.clear();findfac(t);for(BigInteger k: factor.keySet()){System.out.println(k + " " + factor.get(k));}}}

0 0
原创粉丝点击