package hashfinder;

import java.util.*;

/** @author Daniel "3ICE" Berezvai */
public class RandomHashFinder {
  static final String[] codes = {
    "A32BO2", "BPWDH8", "IYIH94", "AMSAKO", "N7OKDZ", "DJQ16O", "WWVK21",
    "JKR7ZR", "DBIOC9", "QG2CBR", "HM02MI", "B21KES", "F3D3D4", "CF2RHU",
    "Q0WQSH", "EYBSWV", "K7FONH", "JP7A43", "ILMJRU"
  };
  static String[] sorted;
  static final Random RNG = new Random();
  static int solutionCount = 0;
  static long iterationCount = 0;
  static int modulo = codes.length;
  static boolean noCollision;
  static int s, bigModulo;
  static int a, b, c, d, e, f, g;
  static int A, B, C, D, E, F;

  public static void main(String[] args) {
    while (solutionCount < 3) {
      iterationCount++;
      if (iterationCount % 100000000 == 0) {
        System.err.println("Tested " + iterationCount + " random combinations.");
      }
      noCollision = true;
      sorted = new String[modulo];

      A = RNG.nextInt(999);
      B = RNG.nextInt(999);
      C = RNG.nextInt(999);
      D = RNG.nextInt(999);
      E = RNG.nextInt(999);
      F = RNG.nextInt(999);

      for (int i = 0; i < codes.length; i++) {
        a = (int) codes[i].charAt(0);
        b = (int) codes[i].charAt(1);
        c = (int) codes[i].charAt(2);
        d = (int) codes[i].charAt(3);
        e = (int) codes[i].charAt(4);
        f = (int) codes[i].charAt(5);
        bigModulo = RNG.nextInt(999) + 1;
        s = ((a * A + b * B + c * C + d * D + e * E + f * F) % bigModulo)
            % modulo;
        if (sorted[s] == null) {
          sorted[s] = codes[i];
        } else {
          noCollision = false;
        }
      }

      if (noCollision) {
        solutionCount++;
        System.out.println("Solution: (" + A + "a+" + B + "b+" + C + "c+" + D
                           + "d+" + E + "e+" + F + "f) (mod " + bigModulo
                           + ") (mod " + modulo + ")");
        for (int i = 0; i < sorted.length; i++) {
          if (sorted[i] != null) {
            System.out.print(sorted[i] + "→" + i + "; ");
          } else {
            System.out.print(i + " is unused; ");
          }
        }
        System.out.println();
      }
    }
    System.out.println("Done. Found " + solutionCount + " solutions after "
                       + iterationCount + " iterations.");
  }
}
