June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
106
Task/Multiplicative-order/Java/multiplicative-order.java
Normal file
106
Task/Multiplicative-order/Java/multiplicative-order.java
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MultiplicativeOrder {
|
||||
private static final BigInteger ONE = BigInteger.ONE;
|
||||
private static final BigInteger TWO = BigInteger.valueOf(2);
|
||||
private static final BigInteger THREE = BigInteger.valueOf(3);
|
||||
private static final BigInteger TEN = BigInteger.TEN;
|
||||
|
||||
private static class PExp {
|
||||
BigInteger prime;
|
||||
long exp;
|
||||
|
||||
PExp(BigInteger prime, long exp) {
|
||||
this.prime = prime;
|
||||
this.exp = exp;
|
||||
}
|
||||
}
|
||||
|
||||
private static void moTest(BigInteger a, BigInteger n) {
|
||||
if (!n.isProbablePrime(20)) {
|
||||
System.out.println("Not computed. Modulus must be prime for this algorithm.");
|
||||
return;
|
||||
}
|
||||
if (a.bitLength() < 100) System.out.printf("ord(%s)", a);
|
||||
else System.out.print("ord([big])");
|
||||
if (n.bitLength() < 100) System.out.printf(" mod %s ", n);
|
||||
else System.out.print(" mod [big] ");
|
||||
BigInteger mob = moBachShallit58(a, n, factor(n.subtract(ONE)));
|
||||
System.out.println("= " + mob);
|
||||
}
|
||||
|
||||
private static BigInteger moBachShallit58(BigInteger a, BigInteger n, List<PExp> pf) {
|
||||
BigInteger n1 = n.subtract(ONE);
|
||||
BigInteger mo = ONE;
|
||||
for (PExp pe : pf) {
|
||||
BigInteger y = n1.divide(pe.prime.pow((int) pe.exp));
|
||||
long o = 0;
|
||||
BigInteger x = a.modPow(y, n.abs());
|
||||
while (x.compareTo(ONE) > 0) {
|
||||
x = x.modPow(pe.prime, n.abs());
|
||||
o++;
|
||||
}
|
||||
BigInteger o1 = BigInteger.valueOf(o);
|
||||
o1 = pe.prime.pow(o1.intValue());
|
||||
o1 = o1.divide(mo.gcd(o1));
|
||||
mo = mo.multiply(o1);
|
||||
}
|
||||
return mo;
|
||||
}
|
||||
|
||||
private static List<PExp> factor(BigInteger n) {
|
||||
List<PExp> pf = new ArrayList<>();
|
||||
BigInteger nn = n;
|
||||
Long e = 0L;
|
||||
while (!nn.testBit(e.intValue())) e++;
|
||||
if (e > 0L) {
|
||||
nn = nn.shiftRight(e.intValue());
|
||||
pf.add(new PExp(TWO, e));
|
||||
}
|
||||
BigInteger s = sqrt(nn);
|
||||
BigInteger d = THREE;
|
||||
while (nn.compareTo(ONE) > 0) {
|
||||
if (d.compareTo(s) > 0) d = nn;
|
||||
e = 0L;
|
||||
while (true) {
|
||||
BigInteger[] qr = nn.divideAndRemainder(d);
|
||||
if (qr[1].bitLength() > 0) break;
|
||||
nn = qr[0];
|
||||
e++;
|
||||
}
|
||||
if (e > 0L) {
|
||||
pf.add(new PExp(d, e));
|
||||
s = sqrt(nn);
|
||||
}
|
||||
d = d.add(TWO);
|
||||
}
|
||||
return pf;
|
||||
}
|
||||
|
||||
private static BigInteger sqrt(BigInteger n) {
|
||||
BigInteger b = n;
|
||||
while (true) {
|
||||
BigInteger a = b;
|
||||
b = n.divide(a).add(a).shiftRight(1);
|
||||
if (b.compareTo(a) >= 0) return a;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
moTest(BigInteger.valueOf(37), BigInteger.valueOf(3343));
|
||||
|
||||
BigInteger b = TEN.pow(100).add(ONE);
|
||||
moTest(b, BigInteger.valueOf(7919));
|
||||
|
||||
b = TEN.pow(1000).add(ONE);
|
||||
moTest(b, BigInteger.valueOf(15485863));
|
||||
|
||||
b = TEN.pow(10000).subtract(ONE);
|
||||
moTest(b, BigInteger.valueOf(22801763489L));
|
||||
|
||||
moTest(BigInteger.valueOf(1511678068), BigInteger.valueOf(7379191741L));
|
||||
moTest(BigInteger.valueOf(3047753288L), BigInteger.valueOf(2257683301L));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue