aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs')
-rw-r--r--Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs168
1 files changed, 168 insertions, 0 deletions
diff --git a/Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs b/Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs
new file mode 100644
index 000000000..afb202fa3
--- /dev/null
+++ b/Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs
@@ -0,0 +1,168 @@
+using System.Collections.Generic;
+
+namespace System.Net
+{
+ using System;
+ using System.Numerics;
+ using System.Text;
+
+ /// <summary>
+ /// Extension methods to convert <see cref="System.Numerics.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="System.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="System.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="System.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());
+
+ }
+ }
+} \ No newline at end of file