⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 primechecker.java

📁 factorization.zip
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package javax.math.factorization;

/**
 * <p>Title: Factorization Library</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2004</p>
 * <p>Company: </p>
 * @author Vladimir Silva
 * @version 1.0
 */
import java.math.BigInteger;

/**
 * I am truly sorry about all this awful spagethi code
 * I got it from: Dario Alejandro Alpern (Buenos Aires - Argentina)
 * Last updated October 16th, 2003. See http://www.alpertron.com.ar/ECM.HTM
 * I am not to blame for its crappy design and implementation, but....
 * what the hell. it works!
 * I modified it though, to make it less horrible (extracted the pieces i needed)
 * If you are a brave soul,  try to port this stuff to an object oriented, well-designed
 * structure. I tried, but just gave up....
 */
public class PrimeChecker implements Constants
{

  // Prime checking routine
  // Return codes: 0 = Number is prime.
  //               1 = Number is composite.
  static int ProbabilisticPrimeTest(BigInteger N) {
    long Base,Q;
    int baseNbr, nbrBases, exp, index, j, k;
    long mask;

//    System.out.println("Starting Rabin probabilistic prime check routine.");
    BigNumOps.BigNbrToBigInt(N);


    exp = N.subtract(Constants.BigInt1).getLowestSetBit();

    MontgomeryParams.GetMontgomeryParams();

    Base = 1;
    nbrBases = N.bitLength()/2;
    for (baseNbr=0; baseNbr<nbrBases; baseNbr++) {
      if (Base<3) {
        Base++;
      }
      else {
        calculate_new_prime4:
          do {
          Base+=2;
          for (Q=3; Q*Q<=Base; Q+=2) {     /* Check if Base is prime */
            if (Base%Q == 0) {
              continue calculate_new_prime4;   /* Composite */
            }
          }
          break;                      /* Prime found */
        } while (true);
      }                 /* end if */

      Util.verbose("Rabin probabilistic prime check routine\n\nBase used: "+Base+" ("+baseNbr*100/nbrBases+"%)");

      //System.arraycopy(MontgomeryMultR1, 0, biN, 0, Factorizer.NumberLength);
      System.arraycopy(MontgomeryParams.getR1(), 0, biN, 0, Factorizer.NumberLength);
      index = Factorizer.NumberLength-1;

      mask = Constants.DosALa31;

      for (k=Factorizer.NumberLength*32; k>exp; k--) {
        // MontgomeryMult(biN, biN, biT);
        MontgomeryParams.MontgomeryMult(biN, biN, biT);

        if ((Factorizer.TestNbr[index] & mask) != 0) {
          BigNumOps.MultBigNbrByLongModN(biT, Base, biT);
        }
        System.arraycopy(biT, 0, biN, 0, Factorizer.NumberLength);
        mask /= 2;
        if (mask == 0) {
          index--;
          mask = Constants.DosALa31;
        }
      }
      for (j=0; j<Factorizer.NumberLength; j++) {
        //if (biN[j] != MontgomeryMultR1[j]) {break;}
        if (biN[j] != MontgomeryParams.getR1()[j]) {break;}
      }
      if (j==Factorizer.NumberLength) {continue;}  /* Probable prime, go to next base */
      for (k=0; k<exp; k++) {
        for (j=0; j<Factorizer.NumberLength; j++) {
          //if (biN[j] != MontgomeryMultR1[j]) {break;}
          if (biN[j] != MontgomeryParams.getR1()[j]) {break;}
        }

        if (j==Factorizer.NumberLength) {return 1;}  /* Composite number */

        //AddBigNbr(biN, MontgomeryMultR1, biT);
        BigNumOps.AddBigNbr(biN, MontgomeryParams.getR1(), biT);

        for (j=0; j<Factorizer.NumberLength; j++) {
          if (biT[j] != Factorizer.TestNbr[j]) {break;}
        }
        if (j==Factorizer.NumberLength) {break;}  /* Probable prime, go to next base */

        //MontgomeryMult(biN, biN, biT);
        MontgomeryParams.MontgomeryMult(biN, biN, biT);
        System.arraycopy(biT, 0, biN, 0, Factorizer.NumberLength);
      }
      if (k==exp) {
        return 1;                      /* Composite number */
      }
    }
    return 0;                        /* Indicate probable prime */
  }


  // Prime checking routine
  // Return codes: 0 = Number is prime.
  //               1 = Number is composite.
  static int AprtCle(BigInteger N) {
	int i, j, G, H, I, J, K, P, Q, T, U, W, X;
	int IV, InvX, LEVELnow, NP, PK, PL, PM, SW, VK, TestedQs, TestingQs;
	int QQ, T1, T3, U1, U3, V1, V3;
	int LengthN, LengthS;
	long Mask;
	double dS;

	String primalityString = "";

//	System.out.println("Starting Prime Check routine.");

	BigNumOps.BigNbrToBigInt(N);

	MontgomeryParams.GetMontgomeryParams();
        long[] MontgomeryMultR1 = MontgomeryParams.getR1();

//	if (Computing3Squares == false) {
	      Util.verbose("Testing primality of " + N  + "(" + N.toString().length() + " digits)" +
                                 "\nAPRT-CLE progress: ");
//	}

	j = PK = PL = PM = 0;
	for (I = 0; I < Factorizer.NumberLength; I++) {
	      biS[I] = 0;
	      for (J = 0; J < MAX_PW; J++) {
		    aiJX[J][I] = 0;
	      }
	}


    GetPrimes2Test:
      for (i=0; i< MAX_LEVEL; i++) {
      biS[0] = 2;
      for (I=1; I<Factorizer.NumberLength; I++) {
        biS[I] = 0;
      }
      for (j=0; j<aiNQ[i]; j++) {
        Q = aiQ[j];
        U = aiT[i]*Q;
        do {
          U /= Q;
          BigNumOps.MultBigNbrByLong(biS, Q, biS);
        } while (U % Q == 0);

        // Exit loop if S^2 > N.

        if (BigNumOps.CompareSquare(biS, Factorizer.TestNbr) > 0) {break GetPrimes2Test;}
      }      // End for j
    }        // End for i


    if (i == MAX_LEVEL) {    // too big
      return ProbabilisticPrimeTest(N);
    }
    LEVELnow = i;
    TestingQs = j;
    T = aiT[LEVELnow];
    NP = aiNP[LEVELnow];


    MainStart:
      do {
      for (i=0; i<NP; i++) {
        P = aiP[i];
        SW = TestedQs = 0;
        Q = W = (int)BigNumOps.BigNbrModLong(Factorizer.TestNbr, P*P);
        for (J=P-2; J>0; J--) {
          W = (W*Q)%(P*P);
        }
        if (P>2 && W!=1) {
          SW = 1;
        }
        do {
          for (j=TestedQs; j<=TestingQs; j++) {
            Q = aiQ[j]-1; G = aiG[j];
            K = 0;
            while (Q%P == 0) {
              K++;
              Q /= P;
            }
            Q = aiQ[j];
            if (K == 0) {continue;}

            //if (Computing3Squares == false) {
              Util.verbose(primalityString + "P = "+P+",  Q = "+Q+"  ("+(i*(TestingQs+1)+j)*100/(NP*(TestingQs+1))+"%)");
            //}

            PM = 1;
            for (I=1; I<K; I++) {
              PM = PM*P;
            }
            PL = (P-1)*PM;
            PK = P*PM;
            J = 1;
            for (I=1; I<Q; I++) {
              J = J*G % Q;
              aiIndx[J] = I;
            }
            J = 1;
            for (I=1; I<=Q-2; I++) {
              J = J*G % Q;
              aiF[I] = aiIndx[(Q+1-J) % Q];
            }
            for (I=0; I<PK; I++) {
              for (J=0; J<Factorizer.NumberLength; J++) {
                aiJ0[I][J] = aiJ1[I][J] = 0;
              }
            }
            if (P>2) {
              BigNumOps.JacobiSum(1,1,P,PK,PL,PM,Q);
            }
            else {
              if (K != 1) {
                BigNumOps.JacobiSum(1,1,P,PK,PL,PM,Q);
                for (I=0; I<PK; I++) {
                  for (J=0; J<Factorizer.NumberLength; J++) {
                    aiJW[I][J] = 0;
                  }
                }
                if (K != 2) {
                  for (I=0; I<PM; I++) {
                    for (J=0; J<Factorizer.NumberLength; J++) {
                      aiJW[I][J] = aiJ0[I][J];
                    }
                  }
                  BigNumOps.JacobiSum(2,1,P,PK,PL,PM,Q);
                  for (I=0; I<PM; I++) {
                    for (J=0; J<Factorizer.NumberLength; J++) {
                      aiJS[I][J] = aiJ0[I][J];
                    }
                  }
                  BigNumOps.JS_JW(PK, PL, PM, P);
                  BigNumOps.NormalizeJS(PK, PL, PM, P);
                  for (I=0; I<PM; I++) {
                    for (J=0; J<Factorizer.NumberLength; J++) {
                      aiJ1[I][J] = aiJS[I][J];
                    }
                  }
                  BigNumOps.JacobiSum(3 << (K-3),1 << (K-3),P,PK,PL,PM,Q);
                  for (J=0; J<Factorizer.NumberLength; J++) {
                    for (I=0; I<PK; I++) {
                      aiJW[I][J] = 0;
                    }
                    for (I=0; I<PM; I++) {
                      aiJS[I][J] = aiJ0[I][J];
                    }
                  }
                  BigNumOps.JS_2(PK, PL, PM, P);
                  BigNumOps.NormalizeJS(PK, PL, PM, P);
                  for (I=0; I<PM; I++) {
                    for (J=0; J<Factorizer.NumberLength; J++) {
                      aiJ2[I][J] = aiJS[I][J];
                    }
                  }
                }
              }
            }
            for (J=0; J<Factorizer.NumberLength; J++) {
              aiJ00[0][J] = aiJ01[0][J] = MontgomeryParams.MontgomeryMultR1[J];
              for (I=1; I<PK; I++) {
                aiJ00[I][J] = aiJ01[I][J] = 0;
              }
            }
            VK = (int)BigNumOps.BigNbrModLong(Factorizer.TestNbr,PK);
            for (I=1; I<PK; I++) {
              if (I%P != 0) {
                U1 = 1; U3 = I; V1 = 0; V3 = PK;
                while (V3 != 0) {
                  QQ = U3/V3;
                  T1 = U1 - V1*QQ;
                  T3 = U3 - V3*QQ;
                  U1 = V1; U3 = V3;
                  V1 = T1; V3 = T3;
                }
                aiInv[I] = (U1+PK)%PK;
              }
              else {
                aiInv[I] = 0;
              }
            }
            if (P != 2) {
              for (IV = 0; IV <= 1; IV++) {
                for (X = 1; X < PK; X++) {
                  for (I=0; I<PK; I++) {
                    for (J=0; J<Factorizer.NumberLength; J++) {
                      aiJS[I][J] = aiJ0[I][J];
                    }
                  }
                  if (X%P == 0) {continue;}
                  if (IV == 0) {
                    BigNumOps.LongToBigNbr(X, biExp);
                  }
                  else {
                    BigNumOps.LongToBigNbr(VK * X / PK, biExp);
                    if (VK * X / PK == 0) {continue;}
                  }
                  BigNumOps.JS_E(PK, PL, PM, P);
                  for (I=0; I<PK; I++) {
                    for (J=0; J<Factorizer.NumberLength; J++) {
                      aiJW[I][J] = 0;
                    }
                  }
                  InvX = aiInv[X];
                  for (I=0; I<PK; I++) {
                    J = I*InvX % PK;
                    BigNumOps.AddBigNbrModN(aiJW[J],aiJS[I],aiJW[J]);
                  }
                  BigNumOps.NormalizeJW(PK, PL, PM, P);
                  if (IV == 0) {
                    for (I=0; I<PK; I++) {
                      for (J=0; J<Factorizer.NumberLength; J++) {
                        aiJS[I][J] = aiJ00[I][J];
                      }
                    }
                  }
                  else {
                    for (I=0; I<PK; I++) {
                      for (J=0; J<Factorizer.NumberLength; J++) {
                        aiJS[I][J] = aiJ01[I][J];
                      }
                    }
                  }
                  BigNumOps.JS_JW(PK, PL, PM, P);
                  if (IV == 0) {
                    for (I=0; I<PK; I++) {
                      for (J=0; J<Factorizer.NumberLength; J++) {
                        aiJ00[I][J] = aiJS[I][J];
                      }
                    }
                  }
                  else {
                    for (I=0; I<PK; I++) {
                      for (J=0; J<Factorizer.NumberLength; J++) {
                        aiJ01[I][J] = aiJS[I][J];
                      }
                    }
                  }
                }                // end for X
              }                  // end for IV
            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -