Exemple #1
0
 private GF256Poly buildGenerator(int degree)
 {
     if (degree >= cachedGenerators.Count)
     {
         GF256Poly lastGenerator = (GF256Poly)cachedGenerators[cachedGenerators.Count - 1];
         for (int d = cachedGenerators.Count; d <= degree; d++)
         {
             GF256Poly nextGenerator = lastGenerator.multiply(new GF256Poly(field, new int[] { 1, field.exp(d - 1) }));
             cachedGenerators.Add(nextGenerator);
             lastGenerator = nextGenerator;
         }
     }
     return((GF256Poly)cachedGenerators[degree]);
 }
		private int[] MathForReferenceImplementation(int[] aCoeff, int[] bCoeff, string option)
		{
			GF256 field = GF256.QR_CODE_FIELD;
			GF256Poly aPoly = new GF256Poly(field, aCoeff);
			GF256Poly bPoly = new GF256Poly(field, bCoeff);
			
			switch(option)
			{
				case "xor":
					return aPoly.addOrSubtract(bPoly).Coefficients;
				case "multy":
					return aPoly.multiply(bPoly).Coefficients;
				default:
					throw new ArgumentException("No such test option");
			}
			        
			
		}
        private GF256Poly[] runEuclideanAlgorithm(GF256Poly a, GF256Poly b, int R)
        {
            // Assume a's degree is >= b's
            if (a.Degree < b.Degree)
            {
                GF256Poly temp = a;
                a = b;
                b = temp;
            }

            GF256Poly rLast = a;
            GF256Poly r     = b;
            GF256Poly sLast = field.One;
            GF256Poly s     = field.Zero;
            GF256Poly tLast = field.Zero;
            GF256Poly t     = field.One;

            // Run Euclidean algorithm until r's degree is less than R/2
            while (r.Degree >= R / 2)
            {
                GF256Poly rLastLast = rLast;
                GF256Poly sLastLast = sLast;
                GF256Poly tLastLast = tLast;
                rLast = r;
                sLast = s;
                tLast = t;

                // Divide rLastLast by rLast, with quotient in q and remainder in r
                if (rLast.Zero)
                {
                    // Oops, Euclidean algorithm already terminated?
                    throw new ReedSolomonException("r_{i-1} was zero");
                }
                r = rLastLast;
                GF256Poly q = field.Zero;
                int       denominatorLeadingTerm = rLast.getCoefficient(rLast.Degree);
                int       dltInverse             = field.inverse(denominatorLeadingTerm);
                while (r.Degree >= rLast.Degree && !r.Zero)
                {
                    int degreeDiff = r.Degree - rLast.Degree;
                    int scale      = field.multiply(r.getCoefficient(r.Degree), dltInverse);
                    q = q.addOrSubtract(field.buildMonomial(degreeDiff, scale));
                    r = r.addOrSubtract(rLast.multiplyByMonomial(degreeDiff, scale));
                }

                s = q.multiply(sLast).addOrSubtract(sLastLast);
                t = q.multiply(tLast).addOrSubtract(tLastLast);
            }

            int sigmaTildeAtZero = t.getCoefficient(0);

            if (sigmaTildeAtZero == 0)
            {
                throw new ReedSolomonException("sigmaTilde(0) was zero");
            }

            int       inverse = field.inverse(sigmaTildeAtZero);
            GF256Poly sigma   = t.multiply(inverse);
            GF256Poly omega   = r.multiply(inverse);

            return(new GF256Poly[] { sigma, omega });
        }