Example #1
0
  /**
   * Method based on FFT to find the determinant and the first coefficient of w(x) this suffices to
   * find w(x) completely
   *
   * @param q the polynomial
   * @param n the degree
   * @return The determinant and the first coefficient of w(x).
   */
  static BigInteger[] gzModZ2(Polynomial q, int n) {
    int i;
    int N = 1 << n;

    Polynomial V = new Polynomial(q.coeffs); // V = q
    Polynomial U = new Polynomial(1); // U = 1
    U.setCoeff(0, new BigInteger("1"));
    Polynomial F = new Polynomial(N); // F(x) = x^N +1
    F.setCoeff(0, new BigInteger("1"));
    F.setCoeff(N, new BigInteger("1"));
    Polynomial V2 = new Polynomial(N);

    while (N > 1) {
      V2 = new Polynomial(V.coeffs);
      for (i = 1; i <= V2.degree; i += 2) { // set V2(x) := V(-x)
        V2.coeffs[i] = V2.coeffs[i].negate(); // negate odd coefficients
      }
      V = Polynomial.mod(Polynomial.mult(V, V2), F); // V := V(x) * V(-x) mod f(x)
      U = Polynomial.mod(Polynomial.mult(U, V2), F); // U := U(x) * V(-x) mod f(x)

      // Sanity-check: verify that the odd coefficients in V are zero
      for (i = 1; i <= V.degree; i += 2)
        if (!V.coeffs[i].equals(new BigInteger("0"))) {
          return null;
        }

      // "Compress" the non-zero coefficients of V
      for (i = 1; i <= V.degree / 2; i++) V.coeffs[i] = V.coeffs[2 * i];
      for (; i <= V.degree; i++) V.coeffs[i] = new BigInteger("0");
      V.normalize();

      // Set U to the "compressed" ( U(x) + U(-x) ) /2
      for (i = 0; i <= U.degree / 2; i++) U.coeffs[i] = U.coeffs[2 * i];
      for (; i <= U.degree; i++) U.coeffs[i] = new BigInteger("0");
      U.normalize();

      // Set N := N/2 and update F accordingly
      F.coeffs[N] = new BigInteger("0");
      N >>= 1;
      F.coeffs[N] = new BigInteger("1");
      F.normalize();
    }

    return new BigInteger[] {V.coeffs[0], U.coeffs[0]};
  }
  private static byte[] createBytes(BitBuffer buffer, RSBlock[] rsBlocks) {

    int offset = 0;

    int maxDcCount = 0;
    int maxEcCount = 0;

    int[][] dcdata = new int[rsBlocks.length][];
    int[][] ecdata = new int[rsBlocks.length][];

    for (int r = 0; r < rsBlocks.length; r++) {

      int dcCount = rsBlocks[r].getDataCount();
      int ecCount = rsBlocks[r].getTotalCount() - dcCount;

      maxDcCount = Math.max(maxDcCount, dcCount);
      maxEcCount = Math.max(maxEcCount, ecCount);

      dcdata[r] = new int[dcCount];
      for (int i = 0; i < dcdata[r].length; i++) {
        dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset];
      }
      offset += dcCount;

      Polynomial rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount);
      Polynomial rawPoly = new Polynomial(dcdata[r], rsPoly.getLength() - 1);

      Polynomial modPoly = rawPoly.mod(rsPoly);
      ecdata[r] = new int[rsPoly.getLength() - 1];
      for (int i = 0; i < ecdata[r].length; i++) {
        int modIndex = i + modPoly.getLength() - ecdata[r].length;
        ecdata[r][i] = (modIndex >= 0) ? modPoly.get(modIndex) : 0;
      }
    }

    int totalCodeCount = 0;
    for (int i = 0; i < rsBlocks.length; i++) {
      totalCodeCount += rsBlocks[i].getTotalCount();
    }

    byte[] data = new byte[totalCodeCount];

    int index = 0;

    for (int i = 0; i < maxDcCount; i++) {
      for (int r = 0; r < rsBlocks.length; r++) {
        if (i < dcdata[r].length) {
          data[index++] = (byte) dcdata[r][i];
        }
      }
    }

    for (int i = 0; i < maxEcCount; i++) {
      for (int r = 0; r < rsBlocks.length; r++) {
        if (i < ecdata[r].length) {
          data[index++] = (byte) ecdata[r][i];
        }
      }
    }

    return data;
  }