mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-10-31 08:11:08 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			168 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			168 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 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());
 | |
| 
 | |
|         }
 | |
|     }
 | |
| } |