/// <summary> /// Returns the index form of the given decimal, assuming that this polynomial is a primitive polynomial for a finite field /// </summary> /// <param name="decimalForm"></param> /// <returns></returns> public BigInteger GetIndexForm(BigInteger decimalForm) { if (decimalForm.IsZero) { return(0); // This is by definition } // This is kind of the opposite of performing modulus. Instead of subtracting increasing smaller multiples of the primitive polynomial to cancel out the higher bits until there's only a remainder left, we start with the remainder and add on increasingly larger multiples of the primitive polynomial in order to cancel out the lower bits until only a single bit is set var binary = new BinaryNumber(decimalForm); // The binary version of the given decimal var polynomial = new BinaryNumber(GetNumber()); // The binary version of this polynomial. Note that BinaryNumber's bits are set from most- to least-significant, which is the opposite of a Polynomial // Define a method that will throw an exception if things don't work var throwException = new Action(() => { throw new Exception("This number doesn't work as a primitive polynomial for the given number, because a power of the generator couldn't be found"); }); // Figure out the maximum number of shifts that we'll allow before giving up var maxShifts = BigInteger.Pow(2, polynomial.Count - 1); // We'll look for up to this power of the generator var shifts = new BigInteger(); // Keeps track of the number of shifts that have been made while (binary.Count > 1) // Keep looping as long as there is more than one bit left to cancel out { binary ^= polynomial; // XOR with the polynomial. This gets rid of successively more lower bits while (!binary.LeastSignificantBit() && binary.Count > 1) // Shift right to get rid of trailing zeros { binary.RotateRight(); shifts++; // Keep track of the number of shifts that were made } if (shifts > maxShifts) { throwException(); } } if (binary.First.Value) // We wound up with the number "1" by itself. This means that the index is x^shifts { return(shifts); } else // We wound up with zero. This means that the index form of the given decimal is undefined { throwException(); } // Code shouldn't get this far, but the compiler doesn't recognize that our exception method will always throw an exception throw new NotImplementedException(); }