public static string EncodeWithCheck(byte[] plaintext)
        {
            ContractsCommon.NotNull(plaintext, "plaintext");
            ContractsCommon.ResultIsNonNull <string>();

            return(EncodeWithCheck(new byte[0], plaintext));
        }
        public static string Encode(byte[] plaintext)
        {
            ContractsCommon.NotNull(plaintext, "plaintext");
            ContractsCommon.ResultIsNonNull <string>();

            var plaintextArr = new byte[plaintext.Length + 1];

            Array.Copy(plaintext, 0, plaintextArr, 1, plaintext.Length);
            Array.Reverse(plaintextArr);
            var           workingValue = new BigInteger(plaintextArr);
            StringBuilder sb           = new StringBuilder(plaintext.Length * 138 / 100 + 1);

            while (workingValue.CompareTo(BigInteger.Zero) > 0)
            {
                BigInteger remainder;
                workingValue = BigInteger.DivRem(workingValue, Base, out remainder);
                sb.Append(Alphabet[(int)remainder]);
            }
            Contract.Assert(workingValue.Sign >= 0);
            //sb.Insert(0, Alphabet[(int)workingValue]);

            for (int i = 0; i < plaintext.Length && plaintext[i] == 0; ++i)
            {
                sb.Append(Alphabet[0]);
            }

            var retVal = new char[sb.Length];

            sb.CopyTo(0, retVal, 0, sb.Length);
            Array.Reverse(retVal);
            return(new string(retVal));
        }
        public static byte[] DecodeWithCheck(string enc)
        {
            ContractsCommon.NotNull(enc, "enc");
            Contract.Requires <FormatException>(Contract.ForAll(0, enc.Length, i => Alphabet.IndexOf(enc[i]) != -1));

            byte[] plaintext;
            return(DecodeWithCheck(enc, out plaintext) ? plaintext : null);
        }
        public static void WriteBytesBE(this ushort val, byte[] buffer, int offset)
        {
            ContractsCommon.NotNull(buffer, "buffer");
            ContractsCommon.ValidOffsetLength(0, buffer.Length, offset, UINT16_SIZE, "offset", "offset");

            buffer[offset]     = (byte)(val >> 8);
            buffer[offset + 1] = (byte)val;
        }
        public static bool DecodeWithCheck(string enc, out byte[] plaintext)
        {
            ContractsCommon.NotNull(enc, "enc");
            Contract.Requires <FormatException>(Contract.ForAll(0, enc.Length, i => Alphabet.IndexOf(enc[i]) != -1));
            Contract.Ensures(Contract.Result <bool>() == false || Contract.ValueAtReturn(out plaintext) != null);

            byte[] prefix;
            return(DecodeWithCheck(enc, 0, out prefix, out plaintext));
        }
        public static void WriteBytes(this uint val, byte[] buffer, int offset)
        {
            ContractsCommon.NotNull(buffer, "buffer");
            ContractsCommon.ValidOffsetLength(0, buffer.Length, offset, UINT32_SIZE, "offset", "offset");

            buffer[offset]     = (byte)val;
            buffer[offset + 1] = (byte)(val >> 8);
            buffer[offset + 2] = (byte)(val >> 16);
            buffer[offset + 3] = (byte)(val >> 24);
        }
        public static byte[] ToBytesArrayBE(this BigInteger bi)
        {
            ContractsCommon.ResultIsNonNull <byte[]>();
            Contract.Ensures(Contract.Result <byte[]>().Length == bi.ToByteArray().Length);

            var resultArray = bi.ToByteArray();

            Array.Reverse(resultArray);
            return(resultArray);
        }
        public static ushort ReadUInt16BE(this byte[] buffer, int offset)
        {
            ContractsCommon.NotNull(buffer, "buffer");
            ContractsCommon.ValidOffsetLength(0, buffer.Length, offset, UINT16_SIZE, "offset", "offset");

            ushort val = (ushort)(((uint)buffer[offset]) << 8);

            val |= buffer[offset + 1];

            return(val);
        }
        public static uint ReadUInt32(this byte[] buffer, int offset)
        {
            ContractsCommon.NotNull(buffer, "buffer");
            ContractsCommon.ValidOffsetLength(0, buffer.Length, offset, UINT32_SIZE, "offset", "offset");

            uint val = buffer[offset];

            val |= ((uint)buffer[offset + 1]) << 8;
            val |= ((uint)buffer[offset + 2]) << 16;
            val |= ((uint)buffer[offset + 3]) << 24;

            return(val);
        }
        public static void WriteBytesBE(this ulong val, byte[] buffer, int offset)
        {
            ContractsCommon.NotNull(buffer, "buffer");
            ContractsCommon.ValidOffsetLength(0, buffer.Length, offset, UINT64_SIZE, "offset", "offset");

            buffer[offset]     = (byte)(val >> 56);
            buffer[offset + 1] = (byte)(val >> 48);
            buffer[offset + 2] = (byte)(val >> 40);
            buffer[offset + 3] = (byte)(val >> 32);
            buffer[offset + 4] = (byte)(val >> 24);
            buffer[offset + 5] = (byte)(val >> 16);
            buffer[offset + 6] = (byte)(val >> 8);
            buffer[offset + 7] = (byte)val;
        }
        public static string EncodeWithCheck(byte[] prefix, byte[] plaintext)
        {
            ContractsCommon.NotNull(prefix, "prefix");
            ContractsCommon.NotNull(plaintext, "plaintext");
            ContractsCommon.ResultIsNonNull <string>();

            var plaintextArr      = (byte[])plaintext.Clone();
            var hash              = Cryptography.CryptoFunctionProviderFactory.Default.Hash256(plaintextArr, prefix);
            var plaintextExtended = new byte[plaintext.Length + prefix.Length + 4];

            Array.Copy(plaintext, 0, plaintextExtended, 0, plaintext.Length);
            Array.Copy(prefix, 0, plaintextExtended, plaintext.Length, prefix.Length);
            Array.Copy(hash.Bytes, 0, plaintextExtended, prefix.Length + plaintext.Length, 4);
            return(Encode(plaintextExtended));
        }
        public static ulong ReadUInt64BE(this byte[] buffer, int offset)
        {
            ContractsCommon.NotNull(buffer, "buffer");
            ContractsCommon.ValidOffsetLength(0, buffer.Length, offset, UINT64_SIZE, "offset", "offset");

            ulong val = ((ulong)buffer[offset]) << 56;

            val |= ((ulong)buffer[offset + 1]) << 48;
            val |= ((ulong)buffer[offset + 2]) << 40;
            val |= ((ulong)buffer[offset + 3]) << 32;
            val |= ((ulong)buffer[offset + 4]) << 24;
            val |= ((ulong)buffer[offset + 5]) << 16;
            val |= ((ulong)buffer[offset + 6]) << 8;
            val |= buffer[offset + 7];

            return(val);
        }
        public static byte[] Decode(string enc)
        {
            ContractsCommon.NotNull(enc, "enc");
            Contract.Requires <FormatException>(Contract.ForAll(0, enc.Length, i => Alphabet.IndexOf(enc[i]) != -1));
            ContractsCommon.ResultIsNonNull <byte[]>();

            if (enc.Length == 0)
            {
                return(new byte[0]);
            }

            var workingValue = BigInteger.Zero;

            for (int i = 0; i < enc.Length; ++i)
            {
                var index = new BigInteger(Alphabet.IndexOf(enc[i]));
                workingValue = workingValue + index * BigInteger.Pow(Base, enc.Length - 1 - i);
            }

            var retVal = workingValue.ToByteArray();

            Array.Reverse(retVal);
            if (retVal[0] == 0 && workingValue > 0)
            {
                var newBytes = new byte[retVal.Length - 1];
                Array.Copy(retVal, 1, newBytes, 0, newBytes.Length);
                retVal = newBytes;
            }

            var count = 0;

            while (enc[count] == Alphabet[0])
            {
                ++count;
            }

            if (count > 0)
            {
                var newBytes = new byte[retVal.Length + count];
                Array.Copy(retVal, 0, newBytes, count, retVal.Length);
                retVal = newBytes;
            }

            return(retVal);
        }
        public static bool DecodeWithCheck(string enc, int prefixLength, out byte[] prefix, out byte[] plaintext)
        {
            ContractsCommon.NotNull(enc, "enc");
            // Approximate decoded byte size = enc.Length * 100 / 138 + 1
            // Plaintext may be all prefix (-0)
            // Prefix may not include bytes reserved for hash (-4)
            ContractsCommon.ValidLength(0, (enc.Length) * 100 / 138 - 3, prefixLength, "prefixLength");
            Contract.Requires <FormatException>(Contract.ForAll(0, enc.Length, i => Alphabet.IndexOf(enc[i]) != -1));
            Contract.Ensures(Contract.Result <bool>() == false || Contract.ValueAtReturn(out prefix) != null && Contract.ValueAtReturn(out prefix).Length == prefixLength);
            Contract.Ensures(Contract.Result <bool>() == false || Contract.ValueAtReturn(out plaintext) != null);

            var plaintextExtended = Decode(enc);

            if (plaintextExtended.Length < 4 + prefixLength)
            {
                prefix    = new byte[0];
                plaintext = plaintextExtended;
                return(false);
            }

            var hash = Cryptography.CryptoFunctionProviderFactory.Default.Hash256(plaintextExtended, 0, plaintextExtended.Length - 4).Bytes;

            var pre = new byte[prefixLength];

            Array.Copy(plaintextExtended, pre, prefixLength);
            prefix = pre;

            var pt = new byte[plaintextExtended.Length - prefixLength - 4];

            Array.Copy(plaintextExtended, prefixLength, pt, 0, pt.Length);
            plaintext = pt;

            return(hash[0] == plaintextExtended[plaintextExtended.Length - 4] &&
                   hash[1] == plaintextExtended[plaintextExtended.Length - 3] &&
                   hash[2] == plaintextExtended[plaintextExtended.Length - 2] &&
                   hash[3] == plaintextExtended[plaintextExtended.Length - 1]);
        }
 public static void CanWriteToStream(System.IO.Stream stream, string streamParamName, int expectedWriteLength)
 {
     ContractsCommon.NotNull(stream, streamParamName);
     Contract.Requires <ArgumentException>(stream.CanWrite, "Stream does not support writing: '" + streamParamName + "'.");
 }
 public static void CanWriteToStream(System.IO.Stream stream, int expectedWriteLength)
 {
     ContractsCommon.CanWriteToStream(stream, "stream", expectedWriteLength);
 }