Пример #1
0
        /// <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);
        }