package com.eatthepath.idobfuscator;

/**
 * Transforms integers by multiplying them by a "secret" multiplier and reverses transformations by multiplying by the
 * secret's multiplicative inverse.
 *
 * @author <a href="https://github.com/jchambers">Jon Chambers</a>
 */
public class MultiplicativeInverseIntegerTransformer implements IntegerTransformer {

    final int multiplier;
    final int inverse;

    /**
     * Constructs a new multiplicative inverse transformer with the given multiplier. Multipliers must be positive and
     * coprime with the size of the number space (which, in this case, just means "must not be divisible by 2"). The
     * multiplicative inverse of the given multiplier is derived automatically.
     *
     * @param multiplier the multiplier to use when transforming integers
     */
    public MultiplicativeInverseIntegerTransformer(final int multiplier) {
        if (multiplier <= 0) {
            throw new IllegalArgumentException("Multiplier must be positive");
        } else if (multiplier % 2 == 0) {
            throw new IllegalArgumentException("Multiplier must not be divisible by 2");
        }

        this.multiplier = multiplier;
        this.inverse = this.getMultiplicativeInverse(multiplier);
    }

    /**
     * Transforms the given integer by multiplying it by this transformer's "secret" multiplier.
     *
     * @param i the integer to transform
     *
     * @return the integer multiplied by this transformer's "secret" multiplier
     */
    @Override
    public int transformInteger(final int i) {
        return i * this.multiplier;
    }

    /**
     * Reverses a multiplication transformation by multiplying the given integer by the multiplicative inverse of this
     * transformer's "secret" multiplier.
     *
     * @param i the integer for which to reverse a multiplication transformation
     *
     * @return the original integer
     */
    @Override
    public int reverseTransformInteger(final int i) {
        return i * this.inverse;
    }

    private int getMultiplicativeInverse(final int multiplier) {
        long s = 0, previousS = 1;
        long t = 1, previousT = 0;
        long r = multiplier, previousR = (1L << Integer.SIZE);

        while (r != 0) {
            final long q = previousR / r;

            {
                final long tempR = r;
                r = previousR - (q * r);
                previousR = tempR;
            }

            {
                final long tempS = s;
                s = previousS - (q * s);
                previousS = tempS;
            }

            {
                final long tempT = t;
                t = previousT - (q * t);
                previousT = tempT;
            }
        }

        return (int) previousT;
    }
}

@@ -31,16 +31,46 @@
 cator;%0A%0A
+import java.math.BigInteger;%0A%0A
 /**%0A * T
@@ -1230,16 +1230,22 @@
 nverse =
+ (int)
  this.ge
@@ -1277,16 +1277,30 @@
 ltiplier
+, Integer.SIZE
 );%0A    %7D
@@ -2081,19 +2081,20 @@
 private 
-int
+long
  getMult
@@ -2113,27 +2113,28 @@
 verse(final 
-int
+long
  multiplier)
@@ -2136,99 +2136,207 @@
 lier
-) %7B%0A        long s = 0, previousS = 1;%0A        long t = 1, previousT = 0;%0A        long r = 
+, final int nBits) %7B%0A        BigInteger s = BigInteger.ZERO, previousS = BigInteger.ONE;%0A        BigInteger t = BigInteger.ONE, previousT = BigInteger.ZERO;%0A        BigInteger r = BigInteger.valueOf(
 mult
@@ -2341,16 +2341,17 @@
 ltiplier
+)
 , previo
@@ -2360,23 +2360,19 @@
 R = 
-(1L %3C%3C 
+Big
 Integer.
 SIZE
@@ -2371,37 +2371,72 @@
 ger.
-SIZE);%0A%0A        while (r != 0
+ONE.shiftLeft(nBits);%0A%0A        while (!BigInteger.ZERO.equals(r)
 ) %7B%0A
@@ -2453,20 +2453,26 @@
   final 
-long
+BigInteger
  q = pre
@@ -2481,12 +2481,18 @@
 ousR
- / r
+.divide(r)
 ;%0A%0A 
@@ -2522,28 +2522,34 @@
       final 
-long
+BigInteger
  tempR = r;%0A
@@ -2581,17 +2581,31 @@
 ousR
- - (q * r
+.subtract(q.multiply(r)
 );%0A 
@@ -2685,28 +2685,34 @@
       final 
-long
+BigInteger
  tempS = s;%0A
@@ -2744,17 +2744,31 @@
 ousS
- - (q * s
+.subtract(q.multiply(s)
 );%0A 
@@ -2852,20 +2852,26 @@
   final 
-long
+BigInteger
  tempT =
@@ -2907,17 +2907,31 @@
 ousT
- - (q * t
+.subtract(q.multiply(t)
 );%0A 
@@ -3003,22 +3003,16 @@
   return
- (int)
  previou
@@ -3013,16 +3013,28 @@
 reviousT
+.longValue()
 ;%0A    %7D%0A

Use BigIntegers for calculating multiplicative inverses.