Represents a polynomial whose coefficients are elements of GF(256). Instances of this class are immutable.

Much credit is due to William Rucklidge since portions of this code are an indirect port of his C++ Reed-Solomon implementation.

 public void encode(int[] toEncode, int ecBytes)
 {
     if (ecBytes == 0)
     {
         throw new ArgumentException("No error correction bytes");
     }
     int dataBytes = toEncode.Length - ecBytes;
     if (dataBytes <= 0)
     {
         throw new ArgumentException("No data bytes provided");
     }
     GF256Poly generator = buildGenerator(ecBytes);
     var infoCoefficients = new int[dataBytes];
     Array.Copy(toEncode, 0, infoCoefficients, 0, dataBytes);
     var info = new GF256Poly(field, infoCoefficients);
     info = info.multiplyByMonomial(ecBytes, 1);
     GF256Poly remainder = info.divide(generator)[1];
     int[] coefficients = remainder.Coefficients;
     int numZeroCoefficients = ecBytes - coefficients.Length;
     for (int i = 0; i < numZeroCoefficients; i++)
     {
         toEncode[dataBytes + i] = 0;
     }
     Array.Copy(coefficients, 0, toEncode, dataBytes + numZeroCoefficients, coefficients.Length);
 }
示例#2
0
 /// <summary> Create a representation of GF(256) using the given primitive polynomial.
 /// 
 /// </summary>
 /// <param name="primitive">irreducible polynomial whose coefficients are represented by
 /// the bits of an int, where the least-significant bit represents the constant
 /// coefficient
 /// </param>
 private GF256(int primitive)
 {
     expTable = new int[256];
     logTable = new int[256];
     int x = 1;
     for (int i = 0; i < 256; i++)
     {
         expTable[i] = x;
         x <<= 1; // x = x * 2; we're assuming the generator alpha is 2
         if (x >= 0x100)
         {
             x ^= primitive;
         }
     }
     for (int i = 0; i < 255; i++)
     {
         logTable[expTable[i]] = i;
     }
     // logTable[0] == 0 but this should never be used
     zero = new GF256Poly(this, new[] {0});
     one = new GF256Poly(this, new[] {1});
 }
示例#3
0
        internal GF256Poly[] divide(GF256Poly other)
        {
            if (!field.Equals(other.field))
            {
                throw new ArgumentException("GF256Polys do not have same GF256 field");
            }
            if (other.Zero)
            {
                throw new ArgumentException("Divide by 0");
            }

            GF256Poly quotient = field.Zero;
            GF256Poly remainder = this;

            int denominatorLeadingTerm = other.getCoefficient(other.Degree);
            int inverseDenominatorLeadingTerm = field.inverse(denominatorLeadingTerm);

            while (remainder.Degree >= other.Degree && !remainder.Zero)
            {
                int degreeDifference = remainder.Degree - other.Degree;
                int scale = field.multiply(remainder.getCoefficient(remainder.Degree), inverseDenominatorLeadingTerm);
                GF256Poly term = other.multiplyByMonomial(degreeDifference, scale);
                GF256Poly iterationQuotient = field.buildMonomial(degreeDifference, scale);
                quotient = quotient.addOrSubtract(iterationQuotient);
                remainder = remainder.addOrSubtract(term);
            }

            return new[] {quotient, remainder};
        }
示例#4
0
 internal GF256Poly multiply(GF256Poly other)
 {
     if (!field.Equals(other.field))
     {
         throw new ArgumentException("GF256Polys do not have same GF256 field");
     }
     if (Zero || other.Zero)
     {
         return field.Zero;
     }
     int[] aCoefficients = coefficients;
     int aLength = aCoefficients.Length;
     int[] bCoefficients = other.coefficients;
     int bLength = bCoefficients.Length;
     var 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] = GF256.addOrSubtract(product[i + j], field.multiply(aCoeff, bCoefficients[j]));
         }
     }
     return new GF256Poly(field, product);
 }
示例#5
0
        internal GF256Poly addOrSubtract(GF256Poly other)
        {
            if (!field.Equals(other.field))
            {
                throw new ArgumentException("GF256Polys do not have same GF256 field");
            }
            if (Zero)
            {
                return other;
            }
            if (other.Zero)
            {
                return this;
            }

            int[] smallerCoefficients = coefficients;
            int[] largerCoefficients = other.coefficients;
            if (smallerCoefficients.Length > largerCoefficients.Length)
            {
                int[] temp = smallerCoefficients;
                smallerCoefficients = largerCoefficients;
                largerCoefficients = temp;
            }
            var 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] = GF256.addOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
            }

            return new GF256Poly(field, sumDiff);
        }