/**
* <p>This class contains utility methods for performing mathematical operations over
- * the Galois Field GF(256). Operations use the primitive polynomial
- * x^8 + x^4 + x^3 + x^2 + 1 in calculations.</p>
+ * the Galois Field GF(256). Operations use a given primitive polynomial in calculations.</p>
*
* <p>Throughout this package, elements of GF(256) are represented as an <code>int</code>
* for convenience and speed (but at the cost of memory).
*
* @author srowen@google.com (Sean Owen)
*/
-final class GF256 {
+public final class GF256 {
- private static final int PRIMITIVE = 0x011D;
- private static final int[] exp = new int[256];
- private static final int[] log = new int[256];
+ public static final GF256 QR_CODE_FIELD = new GF256(0x011D); // x^8 + x^4 + x^3 + x^2 + 1
+ public static final GF256 DATA_MATRIX_FIELD = new GF256(0x012D); // x^8 + x^5 + x^3 + x^2 + 1
- static {
+ private final int[] exp;
+ private final int[] log;
+ private final GF256Poly zero;
+ private final GF256Poly one;
+
+ /**
+ * Create a representation of GF(256) using the given primitive polynomial.
+ *
+ * @param primitive irreducible polynomial whose coefficients are represented by
+ * the bits of an int, where the least-significant bit represents the constant
+ * coefficient
+ */
+ private GF256(int primitive) {
+ exp = new int[256];
+ log = new int[256];
int x = 1;
for (int i = 0; i < 256; i++) {
exp[i] = x;
x <<= 1; // x = x * 2; we're assuming the generator alpha is 2
if (x >= 0x100) {
- x ^= PRIMITIVE;
+ x ^= primitive;
}
}
for (int i = 0; i < 255; i++) {
log[exp[i]] = i;
}
// log[0] == 0 but this should never be used
+ zero = new GF256Poly(this, new int[]{0});
+ one = new GF256Poly(this, new int[]{1});
}
- private GF256() {
+ GF256Poly getZero() {
+ return zero;
+ }
+
+ GF256Poly getOne() {
+ return one;
+ }
+
+ /**
+ * @return the monomial representing coefficient * x^degree
+ */
+ GF256Poly buildMonomial(int degree, int coefficient) {
+ if (degree < 0) {
+ throw new IllegalArgumentException();
+ }
+ if (coefficient == 0) {
+ return zero;
+ }
+ int[] coefficients = new int[degree + 1];
+ coefficients[0] = coefficient;
+ return new GF256Poly(this, coefficients);
}
/**
*
* @return sum/difference of a and b
*/
- static int addOrSubtract(int a, int b) {
+ int addOrSubtract(int a, int b) {
return a ^ b;
}
/**
* @return 2 to the power of a in GF(256)
*/
- static int exp(int a) {
+ int exp(int a) {
return exp[a];
}
/**
* @return base 2 log of a in GF(256)
*/
- static int log(int a) {
+ int log(int a) {
if (a == 0) {
throw new IllegalArgumentException();
}
/**
* @return multiplicative inverse of a
*/
- static int inverse(int a) {
+ int inverse(int a) {
if (a == 0) {
throw new ArithmeticException();
}
* @param b
* @return product of a and b in GF(256)
*/
- static int multiply(int a, int b) {
+ int multiply(int a, int b) {
if (a == 0 || b == 0) {
return 0;
}