Skip to content
Closed
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions src/main/java/com/thealgorithms/others/ShorAlgorithm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.thealgorithms.others;

import java.math.BigInteger;
import java.util.Random;

// The algorithm is referred from
// https://www.geeksforgeeks.org/shors-factorization-algorithm/
public class ShorAlgorithm {
// trying to find the order of exponent given the base and the number
private int exponent(BigInteger base, BigInteger number) {
BigInteger result = BigInteger.ONE;
int increment = 0;
while (!result.equals(BigInteger.ONE) || increment == 0) {
result = result.multiply(base).mod(number);
increment++;
}
return increment;
}

// implementing the shor algorithm
public BigInteger[] shorAlgorithm(BigInteger number) {
if (number.mod(new BigInteger("2")).equals(BigInteger.ZERO)) {
BigInteger p = number.divide(new BigInteger("2"));
BigInteger q = new BigInteger("2");
return new BigInteger[] {p, q};
}

Random random = new Random();
BigInteger base = BigInteger.ZERO;
do {
base = new BigInteger(number.bitLength(), random);
} while (base.compareTo(BigInteger.ZERO) <= 0 || base.compareTo(number) >= 0);

BigInteger hcf = base.gcd(number);
if (hcf.compareTo(BigInteger.ONE) > 0) {
return new BigInteger[] {hcf, number.divide(hcf)};
}

int result = exponent(base, number);
if (result % 2 != 0) {
return null;
}

BigInteger congruentResult = base.modPow(BigInteger.valueOf(result / 2), number);
if (congruentResult.equals(number.subtract(BigInteger.ONE))) {
return null;
}

BigInteger p = congruentResult.add(BigInteger.ONE).gcd(number);
BigInteger q = congruentResult.subtract(BigInteger.ONE).gcd(number);

if (!p.equals(BigInteger.ONE) && !q.equals(BigInteger.ONE)) {
return new BigInteger[] {p, q};
}
return null;
}
}
49 changes: 49 additions & 0 deletions src/test/java/com/thealgorithms/others/ShorAlgorithmTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.thealgorithms.others;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;

import java.math.BigInteger;
import org.junit.jupiter.api.Test;

public class ShorAlgorithmTest {
@Test
public void testFactorizationOfEvenNumber() {
ShorAlgorithm shor = new ShorAlgorithm();
BigInteger number = new BigInteger("15");
BigInteger[] factors = shor.shorAlgorithm(number);

assertNotNull(factors, "Factors should not be null for composite numbers.");
assertEquals(2, factors.length, "There should be two factors.");

BigInteger p = factors[0];
BigInteger q = factors[1];

assertEquals(number, p.multiply(q), "Factors should multiply to the original number.");
}

@Test
public void testFactorizationOfPrimeNumber() {
ShorAlgorithm shor = new ShorAlgorithm();
BigInteger number = new BigInteger("13");
BigInteger[] factors = shor.shorAlgorithm(number);

assertNull(factors, "Factors should be null for prime numbers.");
}

@Test
public void testFactorizationOfEvenCompositeNumber() {
ShorAlgorithm shor = new ShorAlgorithm();
BigInteger number = new BigInteger("20");
BigInteger[] factors = shor.shorAlgorithm(number);

assertNotNull(factors, "Factors should not be null for composite numbers.");
assertEquals(2, factors.length, "There should be two factors.");

BigInteger p = factors[0];
BigInteger q = factors[1];

assertEquals(number, p.multiply(q), "Factors should multiply to the original number.");
}
}
Loading