/// <summary> /// Encode a number between 0 and (n|t) (binomial coefficient) into a binary vector of length n with weight t. /// <para>The number is given as a byte array. Only the first s bits are used, where s = floor[log(n|t)].</para> /// </summary> /// /// <param name="N">The "n" integer</param> /// <param name="T">The "t" integer</param> /// <param name="M">The message as a byte array</param> /// /// <returns>The encoded message as GF2Vector</returns> public static GF2Vector Encode(int N, int T, byte[] M) { if (N < T) { throw new ArgumentException("n < t"); } // compute the binomial c = (n|t) BigInteger c = BigMath.Binomial(N, T); // get the number encoded in m BigInteger i = new BigInteger(1, M); // compare if (i.CompareTo(c) >= 0) { throw new ArgumentException("Encoded number too large."); } GF2Vector result = new GF2Vector(N); int nn = N; int tt = T; for (int j = 0; j < N; j++) { c = c.Multiply(BigInteger.ValueOf(nn - tt)).Divide(BigInteger.ValueOf(nn)); nn--; if (c.CompareTo(i) <= 0) { result.SetBit(j); i = i.Subtract(c); tt--; if (nn == tt) { c = ONE; } else { c = (c.Multiply(BigInteger.ValueOf(tt + 1))).Divide(BigInteger.ValueOf(nn - tt)); } } } return(result); }