internal GenericGfPoly[] Divide(GenericGfPoly other) { if (!field.Equals(other.field)) { throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); } if (other.IsZero) { throw new ArgumentException("Divide by 0"); } GenericGfPoly quotient = field.Zero; GenericGfPoly remainder = this; int denominatorLeadingTerm = other.GetCoefficient(other.Degree); int inverseDenominatorLeadingTerm = field.Inverse(denominatorLeadingTerm); while (remainder.Degree >= other.Degree && !remainder.IsZero) { int degreeDifference = remainder.Degree - other.Degree; int scale = field.Multiply(remainder.GetCoefficient(remainder.Degree), inverseDenominatorLeadingTerm); GenericGfPoly term = other.MultiplyByMonomial(degreeDifference, scale); GenericGfPoly iterationQuotient = field.BuildMonomial(degreeDifference, scale); quotient = quotient.AddOrSubtract(iterationQuotient); remainder = remainder.AddOrSubtract(term); } return(new[] { quotient, remainder }); }
internal GenericGfPoly Multiply(GenericGfPoly other) { if (!field.Equals(other.field)) { throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); } if (IsZero || other.IsZero) { return(field.Zero); } int[] aCoefficients = this.coefficients; int aLength = aCoefficients.Length; int[] bCoefficients = other.coefficients; int bLength = bCoefficients.Length; int[] product = new int[aLength + bLength - 1]; for (int i = 0; i < aLength; i++) { int aCoeff = aCoefficients[i]; for (int j = 0; j < bLength; j++) { product[i + j] = GenericGf.AddOrSubtract(product[i + j], field.Multiply(aCoeff, bCoefficients[j])); } } return(new GenericGfPoly(field, product)); }
public void Encode(int[] toEncode, int ecBytes) { if (ecBytes == 0) { return; // throw new ArgumentException("No error correction bytes"); } var dataBytes = toEncode.Length - ecBytes; if (dataBytes <= 0) { return; // throw new ArgumentException("No data bytes provided"); } var generator = BuildGenerator(ecBytes); var infoCoefficients = new int[dataBytes]; Array.Copy(toEncode, 0, infoCoefficients, 0, dataBytes); var info = new GenericGfPoly(field, infoCoefficients); info = info.MultiplyByMonomial(ecBytes, 1); var remainder = info.Divide(generator)[1]; var coefficients = remainder.Coefficients; var numZeroCoefficients = ecBytes - coefficients.Length; for (var i = 0; i < numZeroCoefficients; i++) { toEncode[dataBytes + i] = 0; } Array.Copy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.Length); }
public GenericGf(int primitive, int size, int genBase) { this.primitive = primitive; this.size = size; this.generatorBase = genBase; expTable = new int[size]; logTable = new int[size]; int x = 1; for (int i = 0; i < size; i++) { expTable[i] = x; x <<= 1; // x = x * 2; if (x >= size) { x ^= primitive; x &= size - 1; } } for (int i = 0; i < size - 1; i++) { logTable[expTable[i]] = i; } zero = new GenericGfPoly(this, new[] { 0 }); one = new GenericGfPoly(this, new[] { 1 }); }
internal GenericGfPoly AddOrSubtract(GenericGfPoly other) { if (!field.Equals(other.field)) { throw new ArgumentException("GenericGFPolys do not have same GenericGF field"); } if (IsZero) { return(other); } if (other.IsZero) { return(this); } int[] smallerCoefficients = this.coefficients; int[] largerCoefficients = other.coefficients; if (smallerCoefficients.Length > largerCoefficients.Length) { int[] temp = smallerCoefficients; smallerCoefficients = largerCoefficients; largerCoefficients = temp; } int[] sumDiff = new int[largerCoefficients.Length]; int lengthDiff = largerCoefficients.Length - smallerCoefficients.Length; // Copy high-order terms only found in higher-degree polynomial's coefficients Array.Copy(largerCoefficients, 0, sumDiff, 0, lengthDiff); for (int i = lengthDiff; i < largerCoefficients.Length; i++) { sumDiff[i] = GenericGf.AddOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]); } return(new GenericGfPoly(field, sumDiff)); }