| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 | using System;using System.Collections.Generic;using System.Numerics;using System.Text;namespace Emby.Server.Implementations.Networking.IPNetwork{    /// <summary>    /// Extension methods to convert <see cref="BigInteger"/>    /// instances to hexadecimal, octal, and binary strings.    /// </summary>    public static class BigIntegerExtensions    {        /// <summary>        /// Converts a <see cref="BigInteger"/> to a binary string.        /// </summary>        /// <param name="bigint">A <see cref="BigInteger"/>.</param>        /// <returns>        /// A <see cref="string"/> containing a binary        /// representation of the supplied <see cref="BigInteger"/>.        /// </returns>        public static string ToBinaryString(this BigInteger bigint)        {            var bytes = bigint.ToByteArray();            var idx = bytes.Length - 1;            // Create a StringBuilder having appropriate capacity.            var base2 = new StringBuilder(bytes.Length * 8);            // Convert first byte to binary.            var binary = Convert.ToString(bytes[idx], 2);            // Ensure leading zero exists if value is positive.            if (binary[0] != '0' && bigint.Sign == 1)            {                base2.Append('0');            }            // Append binary string to StringBuilder.            base2.Append(binary);            // Convert remaining bytes adding leading zeros.            for (idx--; idx >= 0; idx--)            {                base2.Append(Convert.ToString(bytes[idx], 2).PadLeft(8, '0'));            }            return base2.ToString();        }        /// <summary>        /// Converts a <see cref="BigInteger"/> to a hexadecimal string.        /// </summary>        /// <param name="bigint">A <see cref="BigInteger"/>.</param>        /// <returns>        /// A <see cref="string"/> containing a hexadecimal        /// representation of the supplied <see cref="BigInteger"/>.        /// </returns>        public static string ToHexadecimalString(this BigInteger bigint)        {            return bigint.ToString("X");        }        /// <summary>        /// Converts a <see cref="BigInteger"/> to a octal string.        /// </summary>        /// <param name="bigint">A <see cref="BigInteger"/>.</param>        /// <returns>        /// A <see cref="string"/> containing an octal        /// representation of the supplied <see cref="BigInteger"/>.        /// </returns>        public static string ToOctalString(this BigInteger bigint)        {            var bytes = bigint.ToByteArray();            var idx = bytes.Length - 1;            // Create a StringBuilder having appropriate capacity.            var base8 = new StringBuilder(((bytes.Length / 3) + 1) * 8);            // Calculate how many bytes are extra when byte array is split            // into three-byte (24-bit) chunks.            var extra = bytes.Length % 3;            // If no bytes are extra, use three bytes for first chunk.            if (extra == 0)            {                extra = 3;            }            // Convert first chunk (24-bits) to integer value.            int int24 = 0;            for (; extra != 0; extra--)            {                int24 <<= 8;                int24 += bytes[idx--];            }            // Convert 24-bit integer to octal without adding leading zeros.            var octal = Convert.ToString(int24, 8);            // Ensure leading zero exists if value is positive.            if (octal[0] != '0')            {                if (bigint.Sign == 1)                {                    base8.Append('0');                }            }            // Append first converted chunk to StringBuilder.            base8.Append(octal);            // Convert remaining 24-bit chunks, adding leading zeros.            for (; idx >= 0; idx -= 3)            {                int24 = (bytes[idx] << 16) + (bytes[idx - 1] << 8) + bytes[idx - 2];                base8.Append(Convert.ToString(int24, 8).PadLeft(8, '0'));            }            return base8.ToString();        }        /// <summary>        ///        /// Reverse a Positive BigInteger ONLY        /// Bitwise ~ operator        ///        /// Input  : FF FF FF FF        /// Width  : 4        /// Result : 00 00 00 00        ///        ///        /// Input  : 00 00 00 00        /// Width  : 4        /// Result : FF FF FF FF        ///        /// Input  : FF FF FF FF        /// Width  : 8        /// Result : FF FF FF FF 00 00 00 00        ///        ///        /// Input  : 00 00 00 00        /// Width  : 8        /// Result : FF FF FF FF FF FF FF FF        ///        /// </summary>        /// <param name="input"></param>        /// <param name="width"></param>        /// <returns></returns>        public static BigInteger PositiveReverse(this BigInteger input, int width)        {            var result = new List<byte>();            var bytes = input.ToByteArray();            var work = new byte[width];            Array.Copy(bytes, 0, work, 0, bytes.Length - 1); // Length -1 : positive BigInteger            for (int i = 0; i < work.Length; i++)            {                result.Add((byte)(~work[i]));            }            result.Add(0); // positive BigInteger            return new BigInteger(result.ToArray());        }    }}
 |