/** * 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; }