Featured

GetBytesClass.cs

GetBytes Arrays, Classes, Structures, Primitives

Updated: Apr-15,2021

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security;
using System.Security.Cryptography;
using System.Text;
/// <summary>
///     Name: GetBytesClass.cs
///     Date: Dec-01,2020
///     Revised: Mar-11,2021
///     Revised: Apr-15, 2021
/// </summary>
public static class GetBytesClass
{
    private static readonly int                      _charSize = sizeof(char);
    private static readonly BinaryFormatter          Formatter = new();
    private static readonly MonitorActionFuncWrapper _maf      = new();
    private static readonly SHA512Managed            _hash     = new();
    public static byte[] GetHashCodeU<T>(this T obj, int bitWidth)
    {
        return _maf.Lock(_hash, () =>
        {
            var buf = GetBytes(obj);
            if (bitWidth < 16 || bitWidth > 512)
                throw new ArgumentException($"Bit Width {bitWidth} must be between 16 and 512.");
            return _hash.ComputeHash(buf).SubByte(0, bitWidth >> 3);
        });
    }
    /// <summary>
    ///     Get a byte array representation of most any object.
    /// </summary>
    [SecurityCritical]
    public static byte[] GetBytes(this object obj)
    {
        if (obj == null)
            throw new ArgumentException("Object cannot be null.");
        var ltype = obj.GetType();
        switch (ltype.Name.Trim('[', ']'))
        {
            case "Byte":
                return !ltype.IsArray ? new[] {(byte) obj} : (byte[]) obj;
            case "Boolean":
                return !ltype.IsArray ? GetBytes((bool) obj) : GetBytes((bool[]) obj);
            case "SByte":
                return !ltype.IsArray ? GetBytes((sbyte) obj) : GetBytes((sbyte[]) obj);
            case "Char":
                return !ltype.IsArray ? GetBytes((char) obj) : GetBytes((char[]) obj);
            case "Int16":
                return !ltype.IsArray ? GetBytes((short) obj) : GetBytes((short[]) obj);
            case "UInt16":
                return !ltype.IsArray ? GetBytes((ushort) obj) : GetBytes((ushort[]) obj);
            case "Int32":
                return !ltype.IsArray ? GetBytes((int) obj) : GetBytes((int[]) obj);
            case "UInt32":
                return !ltype.IsArray ? GetBytes((uint) obj) : GetBytes((uint[]) obj);
            case "Int64":
                return !ltype.IsArray ? GetBytes((long) obj) : GetBytes((long[]) obj);
            case "UInt64":
                return !ltype.IsArray ? GetBytes((ulong) obj) : GetBytes((ulong[]) obj);
            case "Single":
                return !ltype.IsArray ? GetBytes((float) obj) : GetBytes((float[]) obj);
            case "Double":
                return !ltype.IsArray ? GetBytes((double) obj) : GetBytes((double[]) obj);
            case "String":
                return !ltype.IsArray ? GetBytes((string) obj) : GetBytes((string[]) obj);
            case "Decimal":
                return !ltype.IsArray ? GetBytes((decimal) obj) : GetBytes((decimal[]) obj);
            case "DateTime":
                return !ltype.IsArray ? GetBytes((DateTime) obj) : GetBytes((DateTime[]) obj);
            case "SecureString":
                return !ltype.IsArray ? GetBytes((SecureString) obj) : GetBytes((SecureString[]) obj);
            case "xIntX":
                return !ltype.IsArray ? xIntX.GetBytesInt((xIntX) obj) : GetBytes((xIntX[]) obj);
            case "BigInteger":
                return !ltype.IsArray ? ((BigInteger) obj).ToByteArray() : GetBytes((BigInteger[]) obj);
        }
        return ltype.IsArray ? GetUnClassifiedBytesArray(obj) : GetUnClassifiedBytes(obj, ltype);
    }
    private static bool IsValidPrimitive(Type ltype)
    {
        switch (ltype.Name.Trim('[', ']'))
        {
            case "Byte":
            case "Boolean":
            case "SByte":
            case "Char":
            case "Int16":
            case "UInt16":
            case "Int32":
            case "UInt32":
            case "Int64":
            case "UInt64":
            case "Single":
            case "Double":
            case "String":
            case "Decimal":
            case "DateTime":
                return true;
            default:
                return false;
        }
    }
    /// <summary>
    ///     Get Bytes from a single boolean object
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(bool value)
    {
        return new[] {value ? (byte) 1 : (byte) 0};
    }
    /// <summary>
    ///     Get Bytes from an array of boolean objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(bool[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (bool[]) object cannot be null.");
        var seed = new byte[0];
        return value.Aggregate(seed, (Current, bl) => Current.Add(bl.GetBytes()));
    }
    /// <summary>
    ///     Get Bytes from a single byte object
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(byte value)
    {
        return new[] {value};
    }
    /// <summary>
    ///     Get Bytes from a sbyte short object
    ///     (GetBytesClass.cs)
    /// </summary>
    [SecuritySafeCritical]
    private static unsafe byte[] GetBytes(sbyte value)
    {
        var numArray = new byte[1];
        fixed (byte* ptr = numArray)
        {
            *(sbyte*) ptr = value;
        }
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from an array of sbyte objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(sbyte[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (sbyte[]) object cannot be null.");
        var numArray = new byte[value.Length];
        Buffer.BlockCopy(value, 0, numArray, 0, numArray.Length);
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from a single short object
    ///     (GetBytesClass.cs)
    /// </summary>
    [SecuritySafeCritical]
    private static unsafe byte[] GetBytes(short value)
    {
        var numArray = new byte[2];
        fixed (byte* ptr = numArray)
        {
            *(short*) ptr = value;
        }
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from an array of short objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(short[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (short[]) object cannot be null.");
        var numArray = new byte[value.Length * 2];
        Buffer.BlockCopy(value, 0, numArray, 0, numArray.Length);
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from a single unsigned short object
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(ushort value)
    {
        return ((short) value).GetBytes();
    }
    /// <summary>
    ///     Get Bytes from an array of unsigned short objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(ushort[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (ushort[]) object cannot be null.");
        var numArray = new byte[value.Length * 2];
        Buffer.BlockCopy(value, 0, numArray, 0, numArray.Length);
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from a single character object
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(char value)
    {
        return ((short) value).GetBytes();
    }
    /// <summary>
    ///     Get Bytes from an array of character objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(char[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (char[]) object cannot be null.");
        var numArray = new byte[value.Length * 2];
        Buffer.BlockCopy(value, 0, numArray, 0, numArray.Length);
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from a single integer object
    ///     (GetBytesClass.cs)
    /// </summary>
    [SecuritySafeCritical]
    private static unsafe byte[] GetBytes(int value)
    {
        var numArray = new byte[4];
        fixed (byte* ptr = numArray)
        {
            *(int*) ptr = value;
        }
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from an array of integer objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(int[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (int[]) object cannot be null.");
        var numArray = new byte[value.Length * 4];
        Buffer.BlockCopy(value, 0, numArray, 0, numArray.Length);
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from a single unsigned integer object
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(uint value)
    {
        return ((int) value).GetBytes();
    }
    /// <summary>
    ///     Get Bytes from an array of unsigned integer objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(uint[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (uint[]) object cannot be null.");
        var numArray = new byte[value.Length * 4];
        Buffer.BlockCopy(value, 0, numArray, 0, numArray.Length);
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from a single long object
    ///     (GetBytesClass.cs)
    /// </summary>
    private static unsafe byte[] GetBytes(long value)
    {
        var numArray = new byte[8];
        fixed (byte* ptr = numArray)
        {
            *(long*) ptr = value;
        }
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from an array of long objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(long[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (long[]) object cannot be null.");
        var numArray = new byte[value.Length * 8];
        Buffer.BlockCopy(value, 0, numArray, 0, numArray.Length);
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from an array of long objects with index and count
    ///     (GetBytesClass.cs)
    /// </summary>
    public static byte[] GetBytes(long value, int sIndex = 0, int count = 8)
    {
        if (count > 8)
            throw new Exception("Size cannot exceed 8 bytes.");
        return value.GetBytes().SubArray(sIndex, count);
    }
    /// <summary>
    ///     Get Bytes from a single unsigned long object
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(ulong value)
    {
        return GetBytes((long) value);
    }
    public static byte[] GetBytes(this ulong value, int sIndex = 0, int count = 8)
    {
        if (count > 8)
            throw new Exception("Size cannot exceed 8 bytes.");
        return ((long) value).GetBytes().SubArray(sIndex, count);
    }
    /// <summary>
    ///     Get Bytes from an array of unsigned long objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(ulong[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (ulong[]) object cannot be null.");
        var numArray = new byte[value.Length * 8];
        Buffer.BlockCopy(value, 0, numArray, 0, numArray.Length);
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from a single float object
    ///     (GetBytesClass.cs)
    /// </summary>
    [SecuritySafeCritical]
    private static unsafe byte[] GetBytes(float value)
    {
        return (*(int*) &value).GetBytes();
    }
    /// <summary>
    ///     Get Bytes from an array of float objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(float[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (float[]) object cannot be null.");
        var numArray = new byte[value.Length * 4];
        Buffer.BlockCopy(value, 0, numArray, 0, numArray.Length);
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from a single double object
    ///     (GetBytesClass.cs)
    /// </summary>
    private static unsafe byte[] GetBytes(double value)
    {
        return (*(long*) &value).GetBytes();
    }
    /// <summary>
    ///     Get Bytes from an array of double objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(double[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (double[]) object cannot be null.");
        var numArray = new byte[value.Length * 8];
        Buffer.BlockCopy(value, 0, numArray, 0, numArray.Length);
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from a single decimal object
    ///     (GetBytesClass.cs)
    /// </summary>
    private static unsafe byte[] GetBytes(decimal value)
    {
        var array = new byte[16];
        fixed (byte* bp = array)
        {
            *(decimal*) bp = value;
        }
        return array;
    }
    /// <summary>
    ///     Get Bytes from a single DateTime object
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(DateTime value)
    {
        return value.Ticks.GetBytes();
    }
    private static byte[] GetBytes(DateTime[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (DateTime[]) object cannot be null.");
        var sodt = 0;
        unsafe
        {
            sodt = sizeof(DateTime);
        }
        var numArray = new byte[value.Length * sodt];
        for (var i = 0; i < value.Length; i++)
        {
            var dba = value[i].GetBytes();
            Buffer.BlockCopy(dba, 0, numArray, i * sodt, sodt);
        }
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from an array of decimal objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(decimal[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (decimal[]) object cannot be null.");
        var numArray = new byte[value.Length * 16];
        for (var i = 0; i < value.Length; i++)
        {
            var dba = value[i].GetBytes();
            Buffer.BlockCopy(dba, 0, numArray, i * 16, 16);
        }
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from a single string object using a specified Encoding.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static byte[] GetBytes(this string value, Encoding enc = null)
    {
        if (value == null)
            throw new Exception("GetBytes (string) object cannot be null.");
        if (enc == null)
            return Encoding.ASCII.GetBytes(value);
        switch (enc)
        {
            case ASCIIEncoding AsciiEncoding:
            {
                return Encoding.ASCII.GetBytes(value);
            }
            case UnicodeEncoding UnicodeEncoding:
            {
                var ba  = Encoding.Unicode.GetBytes(value);
                var pre = new byte[] {0xff, 0xfe};
                var ra  = new byte[ba.Length + 2];
                Array.Copy(pre, 0, ra, 0, 2);
                Array.Copy(ba,  0, ra, 2, ba.Length);
                return ra;
            }
            case UTF32Encoding Utf32Encoding:
            {
                var ba  = Encoding.UTF32.GetBytes(value);
                var pre = new byte[] {0xff, 0xfe, 0, 0};
                var ra  = new byte[ba.Length + 4];
                Array.Copy(pre, 0, ra, 0, 4);
                Array.Copy(ba,  0, ra, 4, ba.Length);
                return ra;
            }
            case UTF7Encoding Utf7Encoding:
            {
                var ba  = Encoding.UTF7.GetBytes(value);
                var pre = new byte[] {0x2b, 0x2f, 0x76};
                var ra  = new byte[ba.Length + 3];
                Array.Copy(pre, 0, ra, 0, 3);
                Array.Copy(ba,  0, ra, 3, ba.Length);
                return ra;
            }
            case UTF8Encoding Utf8Encoding:
            {
                var ba  = Encoding.UTF8.GetBytes(value);
                var pre = new byte[] {0xef, 0xbb, 0xbf};
                var ra  = new byte[ba.Length + 3];
                Array.Copy(pre, 0, ra, 0, 3);
                Array.Copy(ba,  0, ra, 3, ba.Length);
                return ra;
            }
            default:
                return Encoding.ASCII.GetBytes(value);
        }
    }
    /// <summary>
    ///     Get Bytes from a array of string objects.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static byte[] GetBytes(this string[] value, Encoding enc = null)
    {
        if (value == null)
            throw new Exception("GetBytes (string[]) object cannot be null.");
        var numArray  = new byte[value.Where(ss => ss != null).Sum(ss => ss.Length)];
        var dstOffset = 0;
        foreach (var str in value)
            if (str != null)
            {
                Buffer.BlockCopy(str.GetBytes(enc), 0, numArray, dstOffset, str.Length);
                dstOffset += str.Length;
            }
        return numArray;
    }
    /// <summary>
    ///     Get Bytes from an array of secure string objects
    ///     (GetBytesClass.cs)
    /// </summary>
    private static byte[] GetBytes(SecureString[] value)
    {
        if (value == null)
            throw new Exception("GetBytes (SecureString[]) object cannot be null.");
        var source = new List<byte[]>();
        foreach (var secureString in value)
            if (secureString != null)
            {
                var byteArray = secureString.GetBytes();
                source.Add(byteArray.CloneTo());
            }
        var seed = new byte[source.Sum(ba => ba.Length)];
        return source.Aggregate(seed, (Current, ba) => Current.Add(ba));
    }
    /// <summary>
    ///     Get Bytes from a single secure string object using a specified encoding
    ///     (GetBytesClass.cs)
    /// </summary>
    public static unsafe byte[] GetBytes(this SecureString value, Encoding enc = null)
    {
        if (value == null)
            throw new Exception("GetBytes (SecureString) object cannot be null.");
        if (enc == null)
            enc = Encoding.Default;
        var maxLength = enc.GetMaxByteCount(value.Length);
        var bytes     = IntPtr.Zero;
        var str       = IntPtr.Zero;
        try
        {
            bytes = Marshal.AllocHGlobal(maxLength);
            str   = Marshal.SecureStringToBSTR(value);
            var chars  = (char*) str.ToPointer();
            var bptr   = (byte*) bytes.ToPointer();
            var len    = enc.GetBytes(chars, value.Length, bptr, maxLength);
            var _bytes = new byte[len];
            for (var i = 0; i < len; ++i)
            {
                _bytes[i] = *bptr;
                bptr++;
            }
            return _bytes;
        }
        finally
        {
            if (bytes != IntPtr.Zero)
                Marshal.FreeHGlobal(bytes);
            if (str != IntPtr.Zero)
                Marshal.ZeroFreeBSTR(str);
        }
    }
    private static byte[] GetBytes(xIntX[] value)
    {
        var r = Array.Empty<byte>();
        if (value != null)
            for (var i = 0; i < value.Length; ++i)
            {
                var lb = xIntX.GetBytesInt(value[i]);
                Array.Resize(ref r, r.Length + lb.Length);
                r = r.Add(lb);
            }
        return r;
    }
    private static byte[] GetBytes(BigInteger[] value)
    {
        var r = Array.Empty<byte>();
        if (value != null)
            for (var i = 0; i < value.Length; ++i)
            {
                var lb = GetBytes(value[i]);
                Array.Resize(ref r, r.Length + lb.Length);
                r = r.Add(lb);
            }
        return r;
    }
    private static byte[] GetBytes(BigInteger value)
    {
        return value.ToByteArray();
    }
    /// <summary>
    ///     Gets list of byte arrays from a list of objects of type T.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static List<byte[]> GetBytesObject<T>(this List<T> value)
    {
        return value.Select(o => o.GetBytes()).ToList();
    }
    /// <summary>
    ///     Gets a single object of type T from a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static T ToObject<T>(this byte[] value)
    {
        if (value == null)
            throw new Exception("value cannot be null.");
        using (var stream = new MemoryStream(value))
        {
            var formatter = new BinaryFormatter();
            var result    = (T) formatter.Deserialize(stream);
            return result;
        }
    }
    /// <summary>
    ///     Gets an array of objects of type T from a list of byte arrays.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static T[] ToObject<T>(this List<byte[]> value)
    {
        if (value == null)
            throw new Exception("value cannot be null.");
        if (value.Count == 0)
            throw new Exception("value is empty.");
        var lst = new List<T>();
        foreach (var o in value)
            lst.Add(o.ToObject<T>());
        return lst.ToArray();
    }
    /// <summary>
    ///     Converts a hex string to a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static byte[] HexToBytes(this string hex)
    {
        if (hex.Length % 2 != 0)
            throw new Exception($"Incomplete Hex string {hex}");
        if (!hex.ContainsOnly("0123456789abcdefABCDEFxX"))
            throw new Exception("Error: hexNumber cannot contain characters other than 0-9,a-f,A-F, or xX");
        hex = hex.ToUpper();
        if (hex.IndexOf("0X", StringComparison.OrdinalIgnoreCase) != -1)
            hex = hex.Substring(2);
        return Enumerable.Range(0, hex.Length).Where(x => x % 2 == 0).Select(x => Convert.ToByte(hex.Substring(x, 2), 16)).ToArray();
    }
    /// <summary>
    ///     Converts a byte array to a hex string.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static string ToHexString(this byte[] bytes)
    {
        var sb = new StringBuilder();
        foreach (var b in bytes)
            sb.Append(b.ToString("X2"));
        return sb.ToString();
    }
    /// <summary>
    ///     Converts a hex string to an unsigned long.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static unsafe ulong FromHexStringTo(this string value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        if (value.Length == 0)
            return 0;
        var ba = value.HexToBytes();
        ba = ba.Invert();
        if (ba.Length > 8)
            throw new Exception("Maximum bit width is limited to 64 bits.");
        var len = ba.Length;
        switch (len)
        {
            case 1:
                fixed (byte* ptr = &ba[0])
                {
                    return *ptr;
                }
            case 2:
                fixed (byte* ptr = &ba[0])
                {
                    return *ptr | ((ulong) ptr[1] << 8);
                }
            case 3:
                fixed (byte* ptr = &ba[0])
                {
                    return *ptr | ((ulong) ptr[1] << 8) | ((ulong) ptr[2] << 16);
                }
            case 4:
                fixed (byte* ptr = &ba[0])
                {
                    return *ptr | ((ulong) ptr[1] << 8) | ((ulong) ptr[2] << 16) | ((ulong) ptr[3] << 24);
                }
            case 5:
                fixed (byte* ptr = &ba[0])
                {
                    return *ptr | ((ulong) ptr[1] << 8) | ((ulong) ptr[2] << 16) | ((ulong) ptr[3] << 24) | ((ulong) ptr[4] << 32);
                }
            case 6:
                fixed (byte* ptr = &ba[0])
                {
                    return *ptr | ((ulong) ptr[1] << 8) | ((ulong) ptr[2] << 16) | ((ulong) ptr[3] << 24) | ((ptr[4] | ((ulong) ptr[5] << 8)) << 32);
                }
            case 7:
                fixed (byte* ptr = &ba[0])
                {
                    return *ptr | ((ulong) ptr[1] << 8) | ((ulong) ptr[2] << 16) | ((ulong) ptr[3] << 24) | ((ptr[4] | ((ulong) ptr[5] << 8) | ((ulong) ptr[6] << 16)) << 32);
                }
            case 8:
                fixed (byte* ptr = &ba[0])
                {
                    return *ptr | ((ulong) ptr[1]                                                              << 8) | ((ulong) ptr[2] << 16) | ((ulong) ptr[3] << 24) |
                           ((ptr[4] | ((ulong) ptr[5] << 8) | ((ulong) ptr[6] << 16) | ((ulong) ptr[7] << 24)) << 32);
                }
            default:
                return 0;
        }
    }
    /// <summary>
    ///     Converts a byte array to a hex string.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static string ToBinaryString(this byte[] bytes)
    {
        var len = bytes.Length;
        var sb  = new StringBuilder();
        for (var i = 0; i < len; i++)
            sb.Append(Convert.ToString(bytes[i], 2).PadLeft(8, '0'));
        return sb.ToString();
    }
    /// <summary>
    ///     Converts a binary string to an unsigned long.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static ulong FromBinaryStringTo(this string value)
    {
        var reversed = value.Reverse().ToArray();
        var num      = 0ul;
        for (var p = 0; p < reversed.Count(); p++)
        {
            if (reversed[p] != '1')
                continue;
            num += (ulong) Math.Pow(2, p);
        }
        return num;
    }
    /// <summary>
    ///     Converts a binary string to a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static byte[] GetBytesFromBinaryString(this string value)
    {
        if (!value.ContainsOnly("01"))
            throw new Exception($"Error: Binary string can only contains 0's and 1's. Value:{value}");
        var len   = value.Length;
        var bLen  = (int) Math.Ceiling(len / 8d);
        var bytes = new byte[bLen];
        var size  = 8;
        for (var i = 1; i <= bLen; i++)
        {
            var idx = len - 8 * i;
            if (idx < 0)
            {
                size = 8 + idx;
                idx  = 0;
            }
            bytes[bLen - i] = Convert.ToByte(value.Substring(idx, size), 2);
        }
        return bytes;
    }
    /// <summary>
    ///     Converts a byte array to a octal string.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static string ToOctalString(this byte[] value)
    {
        value = value.Invert();
        var index = value.Length - 1;
        var base8 = new StringBuilder();
        var rem   = value.Length % 3;
        if (rem == 0)
            rem = 3;
        var Base = 0;
        while (rem != 0)
        {
            Base <<= 8;
            Base +=  value[index--];
            rem--;
        }
        base8.Append(Convert.ToString(Base, 8));
        while (index >= 0)
        {
            Base = (value[index] << 16) + (value[index - 1] << 8) + value[index - 2];
            base8.Append(Convert.ToString(Base, 8).PadLeft(8, '0'));
            index -= 3;
        }
        return base8.ToString();
    }
    /// <summary>
    ///     Returns a Boolean value converted from the byte at a specified position.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static bool ToBool(this byte[] value, int pos = 0)
    {
        return BitConverter.ToBoolean(value, pos);
    }
    /// <summary>
    ///     Returns a Character value converted from the byte at a specified position.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static char ToChar(this byte[] value, int pos = 0)
    {
        return BitConverter.ToChar(value, pos);
    }
    public static unsafe byte ToByte(this byte[] value, int pos = 0)
    {
        byte bv;
        fixed (byte* bp = value)
        {
            var bpp = bp + pos;
            bv = *bpp;
            return bv;
        }
    }
    public static unsafe sbyte ToSByte(this byte[] value, int pos = 0)
    {
        fixed (byte* bp = value)
        {
            var ptr = bp + pos;
            if (pos % 2 == 0)
                return *(sbyte*) ptr;
            return (sbyte) *ptr;
        }
    }
    /// <summary>
    ///     Returns a Short value converted from the byte at a specified position.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static short ToShort(this byte[] value, int pos = 0)
    {
        return BitConverter.ToInt16(PadShort(value), pos);
    }
    /// <summary>
    ///     Returns a Unsigned Short value converted from the byte at a specified position.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static ushort ToUShort(this byte[] value, int pos = 0)
    {
        return BitConverter.ToUInt16(PadShort(value), pos);
    }
    /// <summary>
    ///     Returns a Integer value converted from the byte at a specified position.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static int ToInt(this byte[] value, int pos = 0)
    {
        return BitConverter.ToInt32(PadInt(value), pos);
    }
    /// <summary>
    ///     Returns a Unsigned Integer value converted from the byte at a specified position.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static uint ToUInt(this byte[] value, int pos = 0)
    {
        return BitConverter.ToUInt32(PadInt(value), pos);
    }
    /// <summary>
    ///     Returns a Long value converted from the byte at a specified position.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static long ToLong(this byte[] value, int pos = 0)
    {
        return BitConverter.ToInt64(PadLong(value), pos);
    }
    /// <summary>
    ///     Returns a Unsigned Long value converted from the byte at a specified position.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static ulong ToULong(this byte[] value, int pos = 0)
    {
        return BitConverter.ToUInt64(PadLong(value), pos);
    }
    /// <summary>
    ///     Returns a signed 128 Bit value.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static Int128 ToInt128(this byte[] value)
    {
        if (value.Length > 16)
            throw new ArgumentException($"Value length {value.Length} exceeds limit. {16}");
        return new Int128(value);
    }
    /// <summary>
    ///     Returns a Unsigned 128 Bit value.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static UInt128 ToUInt128(this byte[] value)
    {
        if (value.Length > 16)
            throw new ArgumentException($"Value length {value.Length} exceeds limit. {16}");
        return new UInt128(value);
    }
    /// <summary>
    ///     Returns a signed 256 Bit value.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static Int256 ToInt256(this byte[] value)
    {
        if (value.Length > 32)
            throw new ArgumentException($"Value length {value.Length} exceeds limit. {32}");
        return new Int256(value);
    }
    /// <summary>
    ///     Returns a Unsigned 256 Bit value.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static UInt256 ToUInt256(this byte[] value)
    {
        if (value.Length > 32)
            throw new ArgumentException($"Value length {value.Length} exceeds limit. {32}");
        return new UInt256(value);
    }
    /// <summary>
    ///     Returns a signed 512 Bit value.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static Int512 ToInt512(this byte[] value)
    {
        if (value.Length > 64)
            throw new ArgumentException($"Value length {value.Length} exceeds limit. {64}");
        return new Int512(value);
    }
    /// <summary>
    ///     Returns a Unsigned 512 Bit value.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static UInt512 ToUInt512(this byte[] value)
    {
        if (value.Length > 64)
            throw new ArgumentException($"Value length {value.Length} exceeds limit. {64}");
        return new UInt512(value);
    }
    /// <summary>
    ///     Returns a signed 1024 Bit value.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static xIntX ToInt1024(this byte[] value)
    {
        if (value.Length > 128)
            throw new ArgumentException($"Value length {value.Length} exceeds limit. {128}");
        return new xIntX(value, 1024, false);
    }
    /// <summary>
    ///     Returns a Unsigned 1024 Bit value.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static xIntX ToUInt1024(this byte[] value)
    {
        if (value.Length > 128)
            throw new ArgumentException($"Value length {value.Length} exceeds limit. {128}");
        return new xIntX(value, 1024, true);
    }
    public static xIntX ToxIntX(this byte[] value)
    {
        var bl = value.Length * 8;
        return new xIntX(value, bl, false);
    }
    public static BigInteger ToBigInteger(this byte[] value)
    {
        return new(value);
    }
    /// <summary>
    ///     Returns a Float value converted from the byte at a specified position.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static float ToFloat(this byte[] value, int pos = 0)
    {
        return BitConverter.ToSingle(PadInt(value), pos);
    }
    /// <summary>
    ///     Returns a Double value converted from the byte at a specified position.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static double ToDouble(this byte[] value, int pos = 0)
    {
        return BitConverter.ToDouble(PadLong(value), pos);
    }
    /// <summary>
    ///     Returns a Decimal value converted from the byte at a specified position.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static unsafe decimal ToDecimal(this byte[] value, int pos = 0)
    {
        decimal dv;
        fixed (byte* bp = value)
        {
            var bpp = bp + pos;
            dv = *(decimal*) bpp;
        }
        return dv;
    }
    public static decimal ToDecimalL(byte[] src, int offset)
    {
        var i1 = BitConverter.ToInt32(src, offset);
        var i2 = BitConverter.ToInt32(src, offset + 4);
        var i3 = BitConverter.ToInt32(src, offset + 8);
        var i4 = BitConverter.ToInt32(src, offset + 12);
        return new decimal(new[] {i1, i2, i3, i4});
    }
    /// <summary>
    ///     Returns a String value converted from the byte at a specified position.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static string ToString(this byte[] value, int pos = 0)
    {
        return BitConverter.ToString(value, pos);
    }
    /// <summary>
    ///     Returns a Secure String value converted from the byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static SecureString ToSecureString(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        var securestring = new SecureString();
        var asCharA      = value.ToCharArray();
        foreach (var c in asCharA)
            securestring.AppendChar(c);
        return securestring;
    }
    /// <summary>
    ///     Returns a Boolean array converted from a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static bool[] ToBooleanArray(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        var arr = new bool[value.Length];
        Buffer.BlockCopy(value, 0, arr, 0, value.Length);
        return arr;
    }
    /// <summary>
    ///     Returns a Character array converted from a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static char[] ToCharArray(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        var arr = new char[value.Length];
        Buffer.BlockCopy(value, 0, arr, 0, value.Length);
        return arr;
    }
    public static byte[] ToByteArray(this byte[] value, int index = 0, int length = -1)
    {
        if (length == -1)
            length = value.Length - index;
        var ba = new byte[length];
        Buffer.BlockCopy(value, index, ba, 0, length);
        return ba;
    }
    /// <summary>
    ///     Returns a SByte array converted from a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static sbyte[] ToSByteArray(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        var arr = new sbyte[value.Length];
        Buffer.BlockCopy(value, 0, arr, 0, value.Length);
        return arr;
    }
    /// <summary>
    ///     Returns a Short array converted from a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static short[] ToShortArray(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        var arr = new short[value.Length / 2];
        Buffer.BlockCopy(value, 0, arr, 0, value.Length);
        return arr;
    }
    /// <summary>
    ///     Returns a Unsigned Short array converted from a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static ushort[] ToUShortArray(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        var arr = new ushort[value.Length / 2];
        Buffer.BlockCopy(value, 0, arr, 0, value.Length);
        return arr;
    }
    /// <summary>
    ///     Returns a Integer array converted from a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static int[] ToIntArray(this byte[] value, bool pad = false)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        if (pad)
            value = PadInt(value);
        var arr = new int[value.Length / 4];
        Buffer.BlockCopy(value, 0, arr, 0, value.Length);
        return arr;
    }
    /// <summary>
    ///     Returns a Unsigned Integer array converted from a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static uint[] ToUIntArray(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        var arr = new uint[value.Length / 4];
        Buffer.BlockCopy(value, 0, arr, 0, value.Length);
        return arr;
    }
    /// <summary>
    ///     Returns a Long array converted from the byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static long[] ToLongArray(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        var arr = new long[value.Length / 8];
        Buffer.BlockCopy(value, 0, arr, 0, value.Length);
        return arr;
    }
    /// <summary>
    ///     Returns a Unsigned Long array converted from a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static ulong[] ToULongArray(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        var arr = new ulong[value.Length / 8];
        Buffer.BlockCopy(value, 0, arr, 0, value.Length);
        return arr;
    }
    /// <summary>
    ///     Returns a Float array converted from a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static float[] ToFloatArray(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        if (value.Length % 4 != 0)
            throw new Exception("Byte Object length must be a multiple of 4");
        var arr = new List<float>();
        for (var i = 0; i < value.Length; i += 4)
        {
            var f = BitConverter.ToSingle(value.SubByte(i, 4), 0);
            arr.Add(f);
        }
        return arr.ToArray();
    }
    /// <summary>
    ///     Returns a Double array converted from a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static double[] ToDoubleArray(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        if (value.Length % 8 != 0)
            throw new Exception("Byte Object length must be a multiple of 8");
        var arr = new List<double>();
        for (var i = 0; i < value.Length; i += 8)
        {
            var d = BitConverter.ToDouble(value.SubByte(i, 8), 0);
            arr.Add(d);
        }
        return arr.ToArray();
    }
    /// <summary>
    ///     Returns a decimal array converted from a byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static decimal[] ToDecimalArray(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        if (value.Length % 16 != 0)
            throw new Exception("Byte Object length must be a multiple of 16");
        var arr = new List<decimal>();
        for (var i = 0; i < value.Length; i += 16)
        {
            var t = new[]
            {
                value[i], value[i + 1], value[i  + 2], value[i  + 3], value[i + 4], value[i  + 5], value[i  + 6],
                value[i           + 7], value[i  + 8], value[i  + 9], value[i + 10], value[i + 11], value[i + 12],
                value[i           + 13], value[i + 14], value[i + 15]
            };
            arr.Add(t.ToDecimal());
        }
        return arr.ToArray();
    }
    /// <summary>
    ///     Returns a Single String converted from the byte array.
    ///     (GetBytesClass.cs)
    /// </summary>
    public static string ToSingleString(this byte[] value)
    {
        if (value == null)
            throw new Exception("Value cannot be null.");
        var enc = GetEncoding(value);
        switch (enc)
        {
            case ASCIIEncoding AsciiEncoding:
                return Encoding.ASCII.GetString(value);
            case UnicodeEncoding UnicodeEncoding:
                return Encoding.Unicode.GetString(value);
            case UTF32Encoding Utf32Encoding:
                return Encoding.UTF32.GetString(value);
            case UTF7Encoding Utf7Encoding:
                return Encoding.UTF7.GetString(value);
            case UTF8Encoding Utf8Encoding:
                return Encoding.UTF8.GetString(value);
            default:
                return Encoding.ASCII.GetString(value);
        }
    }
    private static Encoding GetEncoding(byte[] Data)
    {
        if (Data == null)
            throw new Exception("Array cannot be null.");
        if (Data.Length < 2)
            return Encoding.Default;
        if (Data[0] == 0xff && Data[1] == 0xfe)
            return Encoding.Unicode;
        if (Data[0] == 0xfe && Data[1] == 0xff)
            return Encoding.BigEndianUnicode;
        if (Data.Length < 3)
            return Encoding.Default;
        if (Data[0] == 0xef && Data[1] == 0xbb && Data[2] == 0xbf)
            return Encoding.UTF8;
        if (Data[0] == 0x2b && Data[1] == 0x2f && Data[2] == 0x76)
            return Encoding.UTF7;
        if (Data.Length < 4)
            return Encoding.Default;
        if (Data[0] == 0xff && Data[1] == 0xfe && Data[2] == 0 && Data[3] == 0)
            return Encoding.UTF32;
        return Encoding.Default;
    }
    public static bool ToBool(this string value)
    {
        bool result = default;
        if (!string.IsNullOrEmpty(value))
            bool.TryParse(value, out result);
        return result;
    }
    public static char ToChar(this string value)
    {
        char result = default;
        if (!string.IsNullOrEmpty(value))
            char.TryParse(value, out result);
        return result;
    }
    public static byte ToByte(this string value)
    {
        byte result = default;
        if (!string.IsNullOrEmpty(value))
            byte.TryParse(value, out result);
        return result;
    }
    public static sbyte ToSByte(this string value)
    {
        sbyte result = default;
        if (!string.IsNullOrEmpty(value))
            sbyte.TryParse(value, out result);
        return result;
    }
    public static short ToInt16(this string value)
    {
        short result = 0;
        if (!string.IsNullOrEmpty(value))
            short.TryParse(value, out result);
        return result;
    }
    public static ushort ToUInt16(this string value)
    {
        ushort result = 0;
        if (!string.IsNullOrEmpty(value))
            ushort.TryParse(value, out result);
        return result;
    }
    public static int ToInt32(this string value)
    {
        var result = 0;
        if (!string.IsNullOrEmpty(value))
            int.TryParse(value, out result);
        return result;
    }
    public static uint ToUInt32(this string value)
    {
        uint result = 0;
        if (!string.IsNullOrEmpty(value))
            uint.TryParse(value, out result);
        return result;
    }
    public static long ToInt64(this string value)
    {
        long result = 0;
        if (!string.IsNullOrEmpty(value))
            long.TryParse(value, out result);
        return result;
    }
    public static ulong ToUInt64(this string value)
    {
        ulong result = 0;
        if (!string.IsNullOrEmpty(value))
            ulong.TryParse(value, out result);
        return result;
    }
    public static float ToFloat(this string value)
    {
        float result = 0;
        if (!string.IsNullOrEmpty(value))
            float.TryParse(value, out result);
        return result;
    }
    public static double ToDouble(this string value)
    {
        double result = 0;
        if (!string.IsNullOrEmpty(value))
            double.TryParse(value, out result);
        return result;
    }
    public static decimal ToDecimal(this string value)
    {
        decimal result = 0;
        if (!string.IsNullOrEmpty(value))
            decimal.TryParse(value, out result);
        return result;
    }
    public static bool ToBool(this char value)
    {
        bool result = default;
        if (!string.IsNullOrEmpty(value.ToString()))
            bool.TryParse(value.ToString(), out result);
        return result;
    }
    public static byte ToByte(this char value)
    {
        byte result = default;
        if (!string.IsNullOrEmpty(value.ToString()))
            byte.TryParse(value.ToString(), out result);
        return result;
    }
    public static sbyte ToSByte(this char value)
    {
        sbyte result = default;
        if (!string.IsNullOrEmpty(value.ToString()))
            sbyte.TryParse(value.ToString(), out result);
        return result;
    }
    public static short ToInt16(this char value)
    {
        short result = 0;
        if (!string.IsNullOrEmpty(value.ToString()))
            short.TryParse(value.ToString(), out result);
        return result;
    }
    public static ushort ToUInt16(this char value)
    {
        ushort result = 0;
        if (!string.IsNullOrEmpty(value.ToString()))
            ushort.TryParse(value.ToString(), out result);
        return result;
    }
    public static int ToInt32(this char value)
    {
        var result = 0;
        if (!string.IsNullOrEmpty(value.ToString()))
            int.TryParse(value.ToString(), out result);
        return result;
    }
    public static uint ToUInt32(this char value)
    {
        uint result = 0;
        if (!string.IsNullOrEmpty(value.ToString()))
            uint.TryParse(value.ToString(), out result);
        return result;
    }
    public static long ToInt64(this char value)
    {
        long result = 0;
        if (!string.IsNullOrEmpty(value.ToString()))
            long.TryParse(value.ToString(), out result);
        return result;
    }
    public static ulong ToUInt64(this char value)
    {
        ulong result = 0;
        if (!string.IsNullOrEmpty(value.ToString()))
            ulong.TryParse(value.ToString(), out result);
        return result;
    }
    public static float ToFloat(this char value)
    {
        float result = 0;
        if (!string.IsNullOrEmpty(value.ToString()))
            float.TryParse(value.ToString(), out result);
        return result;
    }
    public static double ToDouble(this char value)
    {
        double result = 0;
        if (!string.IsNullOrEmpty(value.ToString()))
            double.TryParse(value.ToString(), out result);
        return result;
    }
    public static decimal ToDecimal(this char value)
    {
        decimal result = 0;
        if (!string.IsNullOrEmpty(value.ToString()))
            decimal.TryParse(value.ToString(), out result);
        return result;
    }
    private static byte[] PadLong(byte[] ba)
    {
        var s = ba.Length % 8;
        switch (s)
        {
            case 0:
                break;
            case 1:
                Array.Resize(ref ba, ba.Length + 7);
                ba[ba.Length - 1] = 0;
                ba[ba.Length - 2] = 0;
                ba[ba.Length - 3] = 0;
                ba[ba.Length - 4] = 0;
                ba[ba.Length - 5] = 0;
                ba[ba.Length - 6] = 0;
                ba[ba.Length - 7] = 0;
                break;
            case 2:
                Array.Resize(ref ba, ba.Length + 6);
                ba[ba.Length - 1] = 0;
                ba[ba.Length - 2] = 0;
                ba[ba.Length - 3] = 0;
                ba[ba.Length - 4] = 0;
                ba[ba.Length - 5] = 0;
                ba[ba.Length - 6] = 0;
                break;
            case 3:
                Array.Resize(ref ba, ba.Length + 5);
                ba[ba.Length - 1] = 0;
                ba[ba.Length - 2] = 0;
                ba[ba.Length - 3] = 0;
                ba[ba.Length - 4] = 0;
                ba[ba.Length - 5] = 0;
                break;
            case 4:
                Array.Resize(ref ba, ba.Length + 4);
                ba[ba.Length - 1] = 0;
                ba[ba.Length - 2] = 0;
                ba[ba.Length - 3] = 0;
                ba[ba.Length - 4] = 0;
                break;
            case 5:
                Array.Resize(ref ba, ba.Length + 3);
                ba[ba.Length - 1] = 0;
                ba[ba.Length - 2] = 0;
                ba[ba.Length - 3] = 0;
                break;
            case 6:
                Array.Resize(ref ba, ba.Length + 2);
                ba[ba.Length - 1] = 0;
                ba[ba.Length - 2] = 0;
                break;
            case 7:
                Array.Resize(ref ba, ba.Length + 1);
                ba[ba.Length - 1] = 0;
                break;
        }
        return ba;
    }
    private static byte[] PadInt(byte[] ba)
    {
        var s = ba.Length % 4;
        switch (s)
        {
            case 0:
                break;
            case 1:
                Array.Resize(ref ba, ba.Length + 3);
                ba[ba.Length - 1] = 0;
                ba[ba.Length - 2] = 0;
                ba[ba.Length - 3] = 0;
                break;
            case 2:
                Array.Resize(ref ba, ba.Length + 2);
                ba[ba.Length - 1] = 0;
                ba[ba.Length - 2] = 0;
                break;
            case 3:
                Array.Resize(ref ba, ba.Length + 1);
                ba[ba.Length - 1] = 0;
                break;
        }
        return ba;
    }
    private static byte[] PadShort(byte[] ba)
    {
        var s = ba.Length % 2;
        switch (s)
        {
            case 0:
                break;
            case 1:
                Array.Resize(ref ba, ba.Length + 1);
                ba[ba.Length - 1] = 0;
                break;
        }
        return ba;
    }
    /// <summary>
    ///     Raw byte array from string
    ///     (GetBytesClass.cs)
    /// </summary>
    public static byte[] GetBytesFromString(this string str)
    {
        if (str == null)
            throw new ArgumentNullException("string cannot be null.");
        if (str.Length == 0)
            return Array.Empty<byte>();
        var bytes = new byte[str.Length * sizeof(char)];
        Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }
    /// <summary>
    ///     Raw string from byte array
    ///     (GetBytesClass.cs)
    /// </summary>
    public static string GetStringFromBytes(this byte[] bytes)
    {
        if (bytes == null)
            throw new ArgumentNullException("bytes cannot be null.");
        if (bytes.Length % _charSize != 0)
            throw new ArgumentException("Invalid bytes length");
        if (bytes.Length == 0)
            return string.Empty;
        var chars = new char[bytes.Length / sizeof(char)];
        Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
        return new string(chars);
    }
    /// <summary>
    ///     Takes a byte array and converts it to a non-serialized object
    ///     (GetBytesClass.cs)
    /// </summary>
    public static T NonSerialByteArrayToObject<T>(this byte[] data)
    {
        var target = (T) Activator.CreateInstance(typeof(T), null);
        using (var ms = new MemoryStream(data))
        {
            byte[] ba    = null;
            var    infos = typeof(T).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            foreach (var info in infos)
            {
                ba = new byte[sizeof(int)];
                ms.Read(ba, 0, sizeof(int));
                var size = BitConverter.ToInt32(ba, 0);
                ba = new byte[size];
                ms.Read(ba, 0, size);
                var bf = new BinaryFormatter();
                using (var ms1 = new MemoryStream(ba))
                {
                    info.SetValue(target, bf.Deserialize(ms1));
                }
            }
        }
        return target;
    }
    /// <summary>
    ///     Takes a non-serialized object and converts it into a byte array
    ///     (GetBytesClass.cs)
    /// </summary>
    public static byte[] SerializeObjectNonSerial<T>(T obj)
    {
        using (var ms = new MemoryStream())
        {
            var infos = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            foreach (var info in infos)
            {
                var bf = new BinaryFormatter();
                using (var inMStream = new MemoryStream())
                {
                    var v = info.GetValue(obj);
                    if (v != null)
                    {
                        bf.Serialize(inMStream, v);
                        var ba = inMStream.ToArray();
                        ms.Write(ba.Length.GetBytes(), 0, sizeof(int));
                        ms.Write(ba,                   0, ba.Length);
                    }
                }
            }
            return ms.ToArray();
        }
    }
    private static IEnumerable<FieldInfo> GetAllFields(Type type)
    {
        return type.GetNestedTypes().SelectMany(GetAllFields).Concat(type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));
    }
    [SecurityCritical]
    private static byte[] GetUnClassifiedBytesArray(object obj)
    {
        if (obj == null)
            throw new ArgumentException("Object cannot be null.");
        if (!obj.GetType().IsArray)
            throw new ArgumentException("Object type needs to be of type array.");
        var aObj = ((IEnumerable) obj).Cast<object>().ToArray();
        var ba   = new List<byte[]>();
        for (var i = 0; i < aObj.Length; ++i)
            ba.Add(GetUnClassifiedBytes(aObj[i], aObj[i].GetType()));
        var ba1 = ba.SelectMany(a => a).ToArray();
        return ba1;
    }
    [SecurityCritical]
    private static byte[] GetUnClassifiedBytes(object obj, Type type)
    {
        if (obj == null)
            throw new ArgumentException("Object cannot be null.");
        var af = GetAllFields(type);
        using (var ms = new RawMemoryStreamWriter())
        {
            foreach (var infon in af)
            {
                var v = infon.IsStatic ? infon.GetValue(null) : infon.GetValue(obj);
                if (v != null)
                    ms.Write(v);
            }
            if (ms.BaseStream.Length == 0)
                throw new Exception("Value and Reference Types, no meaningful data can be found.");
            return ms.BaseStream.ToArray();
        }
    }
    [SecurityCritical]
    public static byte[] GetBytesReflection(this object obj)
    {
        var ltype = obj.GetType();
        return GetUnClassifiedBytes(obj, ltype);
    }
    /// <summary>
    ///     Serialize a serializable object
    ///     (GetBytesClass.cs)
    /// </summary>
    public static byte[] SerializeObject(this object obj)
    {
        using (var stream = new MemoryStream())
        {
            Formatter.Serialize(stream, obj);
            return stream.ToArray();
        }
    }
    /// <summary>
    ///     DeSerialize a serialized object
    ///     (GetBytesClass.cs)
    /// </summary>
    public static T DeserializeObject<T>(this byte[] bytes)
    {
        using (var stream = new MemoryStream(bytes))
        {
            var result = (T) Formatter.Deserialize(stream);
            return result;
        }
    }
    public static byte[] ObjectToByteArray(this object obj)
    {
        if (obj == null)
            return null;
        var bf = new BinaryFormatter();
        var ms = new MemoryStream();
        bf.Serialize(ms, obj);
        return ms.ToArray();
    }
    public static object ByteArrayToObject(this byte[] arrBytes)
    {
        var memStream = new MemoryStream();
        var binForm   = new BinaryFormatter();
        memStream.Write(arrBytes, 0, arrBytes.Length);
        memStream.Seek(0, SeekOrigin.Begin);
        var obj = binForm.Deserialize(memStream);
        return obj;
    }
}

RandomBigInt.cs

BigInteger Random Number Generator

using System;
using System.Numerics;
using System.Security.Cryptography;
public struct RandomBigInt
{
    private readonly RNGCryptoServiceProvider _crng;
    private          int                      _maxByteWidth;
    private          int                      _bitWidth;
    public RandomBigInt(int bitWidth)
    {
        MaxValue      = BigIntegerHelper.GetMaxValueBitWidth(bitWidth);
        _maxByteWidth = bitWidth >> 3;
        OddsOnly      = false;
        Unsigned      = false;
        _crng         = new RNGCryptoServiceProvider();
        _bitWidth     = bitWidth;
    }
    public bool OddsOnly;
    public bool Unsigned;
    public int BitWidth
    {
        get => _bitWidth;
        set
        {
            _bitWidth     = value;
            MaxValue      = BigIntegerHelper.GetMaxValueBitWidth(_bitWidth);
            _maxByteWidth = _bitWidth >> 3;
        }
    }
    public BigInteger MaxValue;
    public bool NextBool()
    {
        return Sample() < .5;
    }
    public BigInteger Next()
    {
        return Internal();
    }
    public BigInteger Next(BigInteger minValue, BigInteger maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        return (BigInteger) (Sample() * (maxValue - minValue)) + minValue;
    }
    public BigInteger Next(BigInteger maxValue)
    {
        if (maxValue < 0)
            throw new ArgumentException("maxValue must be greater than zero.");
        return (BigInteger) (Sample() * maxValue);
    }
    public unsafe double NextDouble()
    {
        var buf = new byte[8];
        GetBytes(buf);
        fixed (byte* ptr = buf)
        {
            return *(ulong*) ptr * (1.0 / ulong.MaxValue) * ulong.MaxValue;
        }
    }
    public BigRational NextBigRational()
    {
        return new(Internal(), Internal());
    }
    public decimal NextDecimal()
    {
        return new((int) Next(int.MaxValue), (int) Next(int.MaxValue), (int) Next(int.MaxValue), NextBool(), (byte) Next(255));
    }
    public BigDecimal NextBigDecimal()
    {
        return Sample();
    }
    public byte[] GetNextByteArray(int size)
    {
        var ba = new byte[size];
        _crng.GetBytes(ba);
        return ba;
    }
    public char[] GetNextCharArray(int size)
    {
        var xbc = new byte[1];
        var ca  = new char[size];
        var ptr = 0;
        do
        {
            _crng.GetBytes(xbc);
            var c = xbc[0];
            if (c >= 0x20 && c <= 0x7F)
                ca[ptr++] = (char) c;
        } while (ptr < size);
        return ca;
    }
    public char NextChar()
    {
        var xbc = new byte[1];
        while (true)
        {
            _crng.GetBytes(xbc);
            var c = xbc[0];
            if (c >= 0x20 && c <= 0x7F)
                return (char) c;
        }
    }
    public bool[] GetNextBoolArrayLimit(int size)
    {
        var        ba = new bool[size];
        const uint ll = uint.MaxValue >> 1;
        for (var i = 0; i < size; ++i)
            ba[i] = Next(0, uint.MaxValue) > ll;
        return ba;
    }
    public byte[] GetNextByteArrayLimit(int size, ulong minValue, ulong maxValue)
    {
        var ba = new byte[size];
        for (var i = 0; i < size; ++i)
            ba[i] = (byte) Next(minValue, maxValue);
        return ba;
    }
    public string GetRandomString(int Len)
    {
        return new(GetNextCharArray(Len));
    }
    public string GetRandomString(int minLen, int maxLen)
    {
        return minLen == maxLen ? new string(GetNextCharArray(minLen)) : new string(GetNextCharArray((int) Next((uint) minLen, (uint) maxLen)));
    }
    private BigDecimal Sample()
    {
        var i = Internal();
        var s = i * (BigDecimal.One / MaxValue);
        if (s.Sign == -1)
            s = s * -1;
        if (s.IsZero)
            throw new Exception("Sample is zero.");
        return s;
    }
    public void GetBytes(byte[] data)
    {
        if (data == null)
            throw new ArgumentException("The buffer cannot be null.");
        _crng.GetBytes(data);
    }
    private BigInteger Internal()
    {
        if (Unsigned)
        {
            var buffer = new byte[_maxByteWidth + 1];
            _crng.GetBytes(buffer);
            buffer[_maxByteWidth] = 0;
            var n = new BigInteger(buffer);
            return !OddsOnly ? n : n | 1;
        }
        else
        {
            var buffer = new byte[_maxByteWidth];
            _crng.GetBytes(buffer);
            var n = new BigInteger(buffer);
            return !OddsOnly ? n : n | 1;
        }
    }
    public void NextBytes(byte[] buffer)
    {
        if (buffer == null)
            throw new ArgumentNullException("The buffer cannot be null.");
        for (var index = 0; index < buffer.Length; ++index)
            buffer[index] = (byte) (Sample() * byte.MaxValue + 1);
    }
    public void GetNonZeroBytes(byte[] buffer)
    {
        if (buffer == null)
            throw new ArgumentNullException("The buffer cannot be null.");
        var index = 0;
        do
        {
            var v = (byte) (Sample() * byte.MaxValue + 1);
            if (v > 0)
            {
                buffer[index] = v;
                index++;
            }
        } while (index < buffer.Length);
    }
    public string[] GetUniqueStringArray(int numberItems, int minLen, int maxLen)
    {
        var sl = new MSet15<string>();
        do
        {
            sl.Add(GetRandomString(minLen, maxLen));
        } while (sl.Count < numberItems);
        return sl.ToArray();
    }
}

ObjectAssociativeArray.cs

Key based, Fast Searchable Values, Multiple Value Arrays.

Key, Values, Values,… All Comparisons are done at the byte level, no need for custom comparator. Keys and all values are searchable, using (Indexed) variable bit width map hashing (Default is 64 Bits, can go up to 512 bits).

using System;
using System.Diagnostics;
[DebuggerDisplay("Count = {" + nameof(Count) + "}")]
[Serializable]
public class ObjectAssociativeArray : MonitorActionFuncWrapper
{
    private ObjectBase   _keys;
    private ObjectBase[] _values;
    public ObjectAssociativeArray() : this(1024)
    {
    }
    public ObjectAssociativeArray(int size, int order = 1)
    {
        _keys   = new ObjectBase(size);
        _values = new ObjectBase[order];
        for (var i = 0; i < order; ++i)
            _values[i] = new ObjectBase(size);
    }
    public int Count => _keys.Count;
    public bool Add(object key, params object[] value)
    {
        if (key == null)
            throw new ArgumentException("Key cannot be null.");
        if (value == null)
            throw new ArgumentException("There must be a least one value.");
        return Lock(this, () =>
        {
            for (var p = 0; p < value.Length; ++p)
                if (_keys.Contains(key) || _values[p].Contains(value[p]))
                    return false;
            var ka = _keys.Add(key);
            var va = false;
            for (var p = 0; p < value.Length; ++p)
            {
                va = _values[p].Add(value[p]);
                if (!va)
                    throw new Exception($"the nth parameter {p} could not be added.");
            }
            return ka && va;
        });
    }
    public (object[] key, object value) GetKeysAndValues(int index)
    {
        return (_keys.ToArray(), _values[index].ToArray());
    }
    #region Generic
    public bool Contains(object key)
    {
        return _keys.Contains(key);
    }
    public bool ContainsValue(object value, int index = 0)
    {
        return _values[index].Contains(value);
    }
    #endregion
}

ObjectDictionary.cs

Object Dictionary Single Associative Array, Searchable Keys and Values

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
[DebuggerDisplay("Count = {Count}")]
[Serializable]
public class ObjectDictionary : MonitorActionFuncWrapper, IEnumerable<KeyValuePair<object, object>>
{
    public ObjectBase _keys;
    public ObjectBase _values;
    public ObjectDictionary() : this(101)
    {
    }
    public ObjectDictionary(int size)
    {
        _keys   = new ObjectBase(size);
        _values = new ObjectBase(size);
    }
    public ObjectDictionary(IEnumerable<KeyValuePair<object, object>> collection)
    {
        foreach (var kp in collection)
            Add(kp.Key, kp.Value);
    }
    public int Count => _keys.Count;
    public object this[object key]
    {
        get
        {
            var pos = _keys.GetObjectIndex(key, false);
            return pos.idx == -1 ? default : _values[pos.idx];
        }
        set => Add(key, value);
    }
    public object[]                       Values        => _values.ToArray();
    public KeyValuePair<object, object>[] KeyValuePairs => ToArray();
    public object[]                       Keys          => _keys.ToArray();
    public IEnumerator<KeyValuePair<object, object>> GetEnumerator()
    {
        return Lock(this, () =>
        {
            return GetEnum();
        });
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return Lock(this, () =>
        {
            return GetEnum();
        });
    }
    private IEnumerator<KeyValuePair<object, object>> GetEnum()
    {
        for (var i = 0; i < Count; i++)
            yield return new KeyValuePair<object, object>(_keys[i], _values[i]);
    }
    public bool Add(object key, object value)
    {
        return Lock(this, () =>
        {
            if (_keys.Contains(key) || _values.Contains(value))
                return false;
            
            var ka = _keys.Add(key);
            var va = _values.Add(value);

            if (ka || va)
            {
                int a = 1;
            }

            return ka && va;
        });
    }
    public void RemoveKey(object key)
    {
        var kidx = _keys.GetObjectIndex(key, false).idx;
        if (kidx != -1)
        {
            var keys   = _keys;
            var values = _values;
            Clear();
            for (var i = 0; i < keys.Count; ++i)
                if (i != kidx)
                    Add(keys[i], values[i]);
        }
    }
    public void RemoveValue(object value)
    {
        var vidx = _values.GetObjectIndex(value, false).idx;
        if (vidx != -1)
        {
            var keys   = _keys;
            var values = _values;
            Clear();
            for (var i = 0; i < keys.Count; ++i)
                if (i != vidx)
                    Add(keys[i], values[i]);
        }
    }
    public void RebuildLists()
    {
        var keys   = _keys;
        var values = _values;
        Clear();
        for (var i = 0; i < keys.Count; ++i)
            Add(keys[i], values[i]);
    }
    public bool ContainsKey(object key)
    {
        return Lock(this, () =>
        {
            return _keys.Contains(key);
        });
    }
    public bool ContainsValue(object value)
    {
        return Lock(this, () =>
        {
            return _values.Contains(value);
        });
    }
    public int FindKeyIndex(object key)
    {
        return Lock(this, () =>
        {
            return _keys.GetObjectIndex(key, false).idx;
        });
    }
    public int FindValueIndex(object value)
    {
        return Lock(this, () =>
        {
            return _values.GetObjectIndex(value, false).idx;
        });
    }
    public KeyValuePair<object, object>[] ToArray()
    {
        return Lock(this, () =>
        {
            var array = new KeyValuePair<object, object>[Count];
            for (var i = 0; i < Count; i++)
                array[i] = new KeyValuePair<object, object>(_keys[i], _values[i]);
            return array;
        });
    }
    public void Clear()
    {
        Lock(this, () =>
        {
            _keys   = new ObjectBase(_keys.Count);
            _values = new ObjectBase(_values.Count);
        });
    }
}

SizeHelper32.cs

Gradually Resize

public class SizeHelper32
{
    private static readonly ulong[] SCurve =
    {
        1024, 1616, 2496, 3776, 5616, 8224, 11873, 16935, 23891, 33376, 46193, 63396, 86336, 116720, 156736, 209152, 277441, 365985, 480262, 627107, 815024, 1054544, 1358704,
        1743552, 2228834, 2838768, 3602962, 4557568, 5746578, 7223456, 9053008, 11313632, 14099984, 17526117, 21729223, 26874016, 33157888, 40817024, 50133527, 61443840, 75148560,
        91723952, 111735408, 135853168, 164870640, 199725776, 241525904, 291576640, 351415424, 422850471, 508005888, 609373904, 729875314, 872929328, 1042534194, 1243360240,
        1480857072, 1761377058, 2092317379, 2482283348, 4964566704, 9929133408, 19858266816, 39716533632, 79433067264, 158866134528, 317732269056, 635464538112, 1270929076224,
        2541858152448, 5083716304896, 10167432609792, 20334865219584, 40669730439168, 81339460878336, 162678921756672, 325357843513344, 650715687026688, 1301431374053376,
        2602862748106752, 5205725496213504, 10411450992427008, 20822901984854016, 41645803969708032, 83291607939416064, 166583215878832128, 333166431757664256, 666332863515328512,
        1332665727030657024, 2665331454061314048, 5330662908122628096, 10661325816245256192, 2875907558780960768, 5751815117561921536, 11503630235123843072, 4560516396538134528,
        9121032793076269056, 18242065586152538112, 18037387098595524608, 17628030123481497600, 16809316173253443584, 15171888272797335552, 11897032471885119488,
        5347320870060687360, 10694641740121374720, 2942539406533197824, 5885078813066395648, 11770157626132791296, 5093571178556030976, 10187142357112061952, 1927540640514572288,
        3855081281029144576, 7710162562058289152, 15420325124116578304, 12393906174523604992, 6341068275337658368, 12682136550675316736, 6917529027641081856, 13835058055282163712,
        9223372036854775808, 18446744073709551615
    };
    private readonly ulong limit = int.MaxValue;
    public ulong GetNewSize(ulong currentSize)
    {
        foreach (var v in SCurve)
        {
            if (v >= limit)
                return limit;
            if (v > currentSize)
                return v;
        }
        return limit;
    }
}

ObjectBase.cs

Base Object Array Class

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Security.Cryptography;
[DebuggerDisplay("Count = {" + nameof(Count) + "}")]
[Serializable]
public class ObjectBase : MonitorActionFuncWrapper, IEnumerable<object>
{
    private readonly EDic20            _map;
    private          object[]          _array;
    private          HashAlgorithm     _hash;
    private          SizeHelper32      _sh = new();
    public           int               Count;
    private          SerializationInfo sInfo;
    public ObjectBase() : this(1024)
    {
    }
    public ObjectBase(int size, int bitWidth = 64)
    {
        BitWidth = bitWidth;
        SelectHashAlgorithm(bitWidth);
        _array = new object[size];
        _map   = new EDic20(size);
    }
    protected ObjectBase(SerializationInfo info, StreamingContext context)
    {
        sInfo = info;
    }
    public int BitWidth
    {
        get;
        private set;
    }
    public object this[object key]
    {
        get
        {
            var pos = GetObjectIndex(key, false);
            return pos.idx == -1 ? default : _array[pos.idx];
        }
        set => Add(key);
    }
    public IEnumerator<object> GetEnumerator()
    {
        return GetEnum();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("BitWidth", BitWidth);
        info.AddValue("Array",    _array, typeof(object[]));
    }
    public void OnDeserialization(object sender)
    {
        if (sInfo == null)
            return;
        BitWidth = sInfo.GetInt32("BitWidth");
        Count    = 0;
        var array = (object[]) sInfo.GetValue("Array", typeof(object[]));
        if (array == null)
            throw new Exception("Array cannot be null.");
        foreach (var t in array)
            Add(t);
    }
    public (List<byte[]> hashes, List<byte[]> bytes, object[] data) GetObjectData()
    {
        var ia = _map._keys.ToArray();
        var ba = new List<byte[]>();
        for (var i = 0; i < _map.Count; ++i)
        {
            var eba = ia[i];
            ba.Add((byte[]) eba.Clone());
        }
        ia = _map._values;
        var ba1 = new List<byte[]>();
        for (var i = 0; i < _map.Count; ++i)
        {
            var eba = ia[i];
            ba1.Add((byte[]) eba.Clone());
        }
        return (ba, ba1, ToArray());
    }
    public bool Add(object item)
    {
        var res = GetObjectIndex(item);
        if (res.idx >= _array.Length)
        {
            var g = (int) _sh.GetNewSize((ulong) _array.Length);
            while ((g & 8) != 0)
                g++;
            Array.Resize(ref _array, g);
        }
        if (res.exists == false)
        {
            _array[res.idx] = item;
            Count++;
        }
        return res.exists == false;
    }
    private IEnumerator<object> GetEnum()
    {
        var ary = _array;
        var cnt = Count;
        for (var i = 0; i < cnt; i++)
            yield return ary[i];
    }
    public object[] ToArray()
    {
        var newArray = new object[Count];
        using (var en = GetEnumerator())
        {
            var ptr = 0;
            while (en.MoveNext())
            {
                var value = en.Current;
                if (value == null)
                    break;
                newArray[ptr++] = value;
            }
            return newArray;
        }
    }
    public bool Contains(object item)
    {
        return MapContains(item);
    }
    private bool MapContains(object obj)
    {
        if (obj == null)
            throw new ArgumentNullException(nameof(obj));
        var bytes = obj.GetBytes();
        var hash  = _hash.ComputeHash(bytes, 0, bytes.Length);
        return _map.ContainsKey(hash);
    }
    internal (int idx, bool exists) GetObjectIndex(object obj, bool add = true)
    {
        var bytes = obj.GetBytes();
        var hash  = new byte[0];
        if (BitWidth == 1024)
            hash = _hash.ComputeHash(bytes, 0, bytes.Length).Add(_hash.ComputeHash(bytes.Invert(), 0, bytes.Length));
        else
            hash = _hash.ComputeHash(bytes, 0, bytes.Length);
        var exists = false;
        if (!_map.ContainsKey(hash))
        {
            if (add)
                _map.Add(hash, bytes);
        }
        else
        {
            exists = true;
        }
        return (_map.FindKeyIndex(hash), exists);
    }
    private void SelectHashAlgorithm(int bitWidth)
    {
        BitWidth = bitWidth;
        switch (bitWidth)
        {
            case 32:
                _hash = new FNV1a32();
                break;
            case 64:
                _hash = new FNV1a64();
                break;
            case 128:
                _hash = new Murmur3();
                break;
            case 256:
                _hash = new SHA256Managed();
                break;
            case 512:
                _hash = new SHA512Managed();
                break;
            case 1024:
                _hash = new SHA512Managed();
                break;
            default:
                throw new ArgumentException("Supported bit widths are: 32, 64, 128, 256, and 512 Bits.");
        }
    }
    internal class EDic20 : IEnumerable<KeyValuePair<byte[], byte[]>>
    {
        internal readonly Set20    _keys;
        internal          byte[][] _values;
        public EDic20() : this(101)
        {
        }
        public EDic20(int size)
        {
            _keys   = new Set20(size);
            _values = new byte[size][];
        }
        public int Count => _keys.Count;
        public IEnumerator<KeyValuePair<byte[], byte[]>> GetEnumerator()
        {
            return GetEnum();
        }
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnum();
        }
        private IEnumerator<KeyValuePair<byte[], byte[]>> GetEnum()
        {
            for (var i = 0; i < Count; i++)
                if (_keys.Slots[i].HashCode > 0)
                    yield return new KeyValuePair<byte[], byte[]>(_keys.Slots[i].Value, _values[i]);
        }
        public bool Add(byte[] key, byte[] value)
        {
            if (!_keys.Add(key))
            {
                if (_values.Length != _keys.Slots.Length)
                {
                    var nValues = new byte[_keys.Slots.Length][];
                    Array.Copy(_values, nValues, _values.Length);
                    _values = nValues;
                }
                _values[_keys.Position] = value;
                return false;
            }
            _values[_keys.Position] = value;
            return true;
        }
        public bool ContainsKey(byte[] key)
        {
            return _keys.FindEntry(key) != -1;
        }
        public int FindKeyIndex(byte[] key)
        {
            return _keys.FindEntry(key);
        }
        internal class Set20
        {
            private readonly IEqualityComparer<byte[]> Comparer;
            private          int[]                     _hashBuckets;
            internal         int                       Position;
            internal         Slot[]                    Slots;
            public Set20(int size)
            {
                Comparer     = new ArrayComparer();
                _hashBuckets = new int[size];
                Slots        = new Slot[size];
                Count        = 0;
                Position     = -1;
            }
            public int Count
            {
                get;
                private set;
            }
            public IEnumerator<byte[]> GetEnumerator()
            {
                for (var i = 0; i < Count; i++)
                    if (Slots[i].HashCode > 0)
                        yield return Slots[i].Value;
            }
            public byte[][] ToArray()
            {
                var newArray = new byte[Count][];
                using (var en = GetEnumerator())
                {
                    var ptr = 0;
                    while (en.MoveNext())
                    {
                        var value = en.Current;
                        if (value == null)
                            break;
                        newArray[ptr++] = value;
                    }
                    return newArray;
                }
            }
            public bool Add(byte[] item)
            {
                var hashCode = Comparer.GetHashCode(item) & int.MaxValue;
                if (FindEntry(item, hashCode) != -1)
                    return true;
                if (Count >= Slots.Length)
                    Resize();
                var hashPos = hashCode % _hashBuckets.Length;
                Slots[Count].Next     = _hashBuckets[hashPos] - 1;
                Slots[Count].Value    = item;
                Slots[Count].HashCode = hashCode;
                _hashBuckets[hashPos] = Count + 1;
                Position              = Count;
                ++Count;
                return false;
            }
            private void Resize()
            {
                var newSize        = (_hashBuckets.Length + _hashBuckets.Length / 4 * 3) | 1;
                var newSlots       = new Slot[newSize];
                var newHashBuckets = new int[newSize];
                var newCount       = 0;
                var en             = GetEnumerator();
                while (en.MoveNext())
                {
                    var item     = en.Current;
                    var hashCode = Comparer.GetHashCode(item) & int.MaxValue;
                    var hashPos  = hashCode % newHashBuckets.Length;
                    newSlots[newCount].Next     = newHashBuckets[hashPos] - 1;
                    newSlots[newCount].Value    = item;
                    newSlots[newCount].HashCode = hashCode;
                    newHashBuckets[hashPos]     = newCount + 1;
                    ++newCount;
                }
                Slots        = newSlots;
                _hashBuckets = newHashBuckets;
                Count        = newCount;
            }
            public int FindEntry(byte[] item, int hashCode)
            {
                for (var position = _hashBuckets[hashCode % _hashBuckets.Length] - 1; position >= 0; position = Slots[position].Next)
                    if (Slots[position].HashCode == hashCode && Comparer.Equals(Slots[position].Value, item))
                    {
                        Position = position;
                        return position;
                    }
                return -1;
            }
            public int FindEntry(byte[] item)
            {
                return FindEntry(item, Comparer.GetHashCode(item) & int.MaxValue);
            }
            internal struct Slot
            {
                public int    HashCode;
                public int    Next;
                public byte[] Value;
            }
        }
    }
}

MSet15.cs

Hashing Set Class

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
[DebuggerDisplay("Count = {" + nameof(Count) + "}")]
[Serializable]
public class MSet15<T>
{
    private  int[]                _hashBuckets;
    internal IEqualityComparer<T> Comparer;
    internal int                  Position;
    internal Slot[]               Slots;
    public   bool                 SlowGrowth;
    public MSet15() : this(31, EqualityComparer<T>.Default)
    {
    }
    public MSet15(int size) : this(size, EqualityComparer<T>.Default)
    {
    }
    public MSet15(IEqualityComparer<T> comparer) : this(31, comparer)
    {
    }
    public MSet15(int size, IEqualityComparer<T> comparer)
    {
        if (comparer == null)
            comparer = EqualityComparer<T>.Default;
        Comparer     = comparer;
        _hashBuckets = new int[size];
        Slots        = new Slot[size];
        Count        = 0;
        Position     = -1;
    }
    public MSet15(IEnumerable<T> collection, IEqualityComparer<T> comparer)
    {
        if (comparer == null)
            comparer = EqualityComparer<T>.Default;
        var enumerable = collection as T[] ?? collection.ToArray();
        var size       = enumerable.Length;
        Comparer     = comparer;
        _hashBuckets = new int[size];
        Slots        = new Slot[size];
        Count        = 0;
        Position     = -1;
        foreach (var i in enumerable)
            Add(i);
    }
    public int Count
    {
        get;
        private set;
    }
    public IEnumerator<T> GetEnumerator()
    {
        for (var i = 0; i < Count; i++)
            if (Slots[i].HashCode > 0)
                yield return Slots[i].Value;
    }
    public bool Add(T item)
    {
        var hashCode = Comparer.GetHashCode(item) & int.MaxValue;
        if (FindEntry(item, hashCode) != -1)
            return true;
        if (Count >= Slots.Length)
            Resize();
        var hashPos = hashCode % _hashBuckets.Length;
        Slots[Count].Next     = _hashBuckets[hashPos] - 1;
        Slots[Count].Value    = item;
        Slots[Count].HashCode = hashCode;
        _hashBuckets[hashPos] = Count + 1;
        Position              = Count;
        ++Count;
        return false;
    }

    public void AddRange(IEnumerable<T> collection)
    {
        foreach (var i in collection)
            Add(i);
    }
    public bool Remove(T item)
    {
        if (Count != 0)
        {
            var hashCode = Comparer.GetHashCode(item) & int.MaxValue;
            var iPos     = hashCode % _hashBuckets.Length;
            var tPos     = -1;
            for (var sPos = _hashBuckets[iPos] - 1; sPos >= 0; sPos = Slots[sPos].Next)
            {
                if (Slots[sPos].HashCode == hashCode && Comparer.Equals(Slots[sPos].Value, item))
                {
                    if (tPos < 0)
                        _hashBuckets[iPos] = Slots[sPos].Next + 1;
                    else
                        Slots[tPos].Next = Slots[sPos].Next;
                    Slots[sPos].HashCode = -1;
                    Slots[sPos].Value    = default;
                    Slots[sPos].Next     = 0;
                    --Count;
                    return true;
                }
                tPos = sPos;
            }
        }
        return false;
    }
    public bool Contains(T item)
    {
        return FindEntry(item, Comparer.GetHashCode(item) & int.MaxValue) != -1;
    }
    public T[] ToArray()
    {
        var newArray = new T[Count];
        using (var en = GetEnumerator())
        {
            var ptr = 0;
            while (en.MoveNext())
            {
                var value = en.Current;
                if (value == null)
                    break;
                newArray[ptr++] = value;
            }
            return newArray;
        }
    }
    private void Resize()
    {
        var newSize        = !SlowGrowth ? _hashBuckets.Length + _hashBuckets.Length / 4 * 3 : _hashBuckets.Length + 1;
        var newSlots       = new Slot[newSize];
        var newHashBuckets = new int[newSize];
        var newCount       = 0;
        var en             = GetEnumerator();
        while (en.MoveNext())
        {
            var item     = en.Current;
            var hashCode = Comparer.GetHashCode(item) & int.MaxValue;
            var hashPos  = hashCode % newHashBuckets.Length;
            newSlots[newCount].Next     = newHashBuckets[hashPos] - 1;
            newSlots[newCount].Value    = item;
            newSlots[newCount].HashCode = hashCode;
            newHashBuckets[hashPos]     = newCount + 1;
            ++newCount;
        }
        Slots        = newSlots;
        _hashBuckets = newHashBuckets;
        Count        = newCount;
    }
    public int FindEntry(T item, int hashCode)
    {
        for (var position = _hashBuckets[hashCode % _hashBuckets.Length] - 1; position >= 0; position = Slots[position].Next)
            if (Slots[position].HashCode == hashCode && Comparer.Equals(Slots[position].Value, item))
            {
                Position = position;
                return position;
            }
        return -1;
    }
    public int FindEntry(T item)
    {
        return FindEntry(item, Comparer.GetHashCode(item) & int.MaxValue);
    }
    internal struct Slot
    {
        public int HashCode;
        public int Next;
        public T   Value;
    }
}

AcDictionary.cs

Support Dictionary for Hash Mapping

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
[DebuggerDisplay("Count = {Count}")]
[Serializable]
public class AcDictionary<TKey, TValue> : MonitorActionFuncWrapper, IEnumerable<KeyValuePair<TKey, TValue>>
{
    public MSet15<TKey> _keys;
    public TValue[]     _values;
    public AcDictionary() : this(101, EqualityComparer<TKey>.Default)
    {
    }
    public AcDictionary(int size) : this(size, EqualityComparer<TKey>.Default)
    {
    }
    public AcDictionary(int size, IEqualityComparer<TKey> comparer)
    {
        if (comparer == null)
            comparer = EqualityComparer<TKey>.Default;
        _keys          = new MSet15<TKey>(size);
        _values        = new TValue[size];
        _keys.Comparer = comparer;
    }
    public AcDictionary(IEnumerable<KeyValuePair<TKey, TValue>> collection, IEqualityComparer<TKey> comparer = null)
    {
        if (comparer == null)
            comparer = EqualityComparer<TKey>.Default;
        _keys.Comparer = comparer;
        foreach (var kp in collection)
            Add(kp.Key, kp.Value);
    }
    public int Count => _keys.Count;
    public TValue this[TKey key]
    {
        get
        {
            var pos = _keys.FindEntry(key);
            return pos == -1 ? default : _values[pos];
        }
        set => Add(key, value);
    }
    public TValue[]                     Values        => _values;
    public KeyValuePair<TKey, TValue>[] KeyValuePairs => ToArray();
    public TKey[]                       Keys          => _keys.ToArray();
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return Lock(this, () =>
        {
            return GetEnum();
        });
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return Lock(this, () =>
        {
            return GetEnum();
        });
    }
    private IEnumerator<KeyValuePair<TKey, TValue>> GetEnum()
    {
        for (var i = 0; i < Count; i++)
            if (_keys.Slots[i].HashCode > 0)
                yield return new KeyValuePair<TKey, TValue>(_keys.Slots[i].Value, _values[i]);
    }
    public bool Add(TKey key, TValue value)
    {
        return Lock(this, () =>
        {
            if (!_keys.Add(key))
            {
                if (Values.Length != _keys.Slots.Length)
                {
                    var nValues = new TValue[_keys.Slots.Length];
                    Array.Copy(_values, nValues, _values.Length);
                    _values = nValues;
                }
                Values[_keys.Position] = value;
                return false;
            }
            Values[_keys.Position] = value;
            return true;
        });
    }
    public void Remove(TKey key)
    {
        Lock(this, () =>
        {
            var pos = _keys.FindEntry(key);
            if (pos != -1)
            {
                Values[pos] = default;
                _keys.Remove(key);
            }
        });
    }
    public bool ContainsKey(TKey key)
    {
        return Lock(this, () =>
        {
            return _keys.FindEntry(key) != -1;
        });
    }
    public bool ContainsValue(TValue value)
    {
        return Lock(this, () =>
        {
            var vab = value.GetBytes();
            foreach (var v in _values)
            {
                if (v == null)
                    continue;
                var vab1 = v.GetBytes();
                if (vab.Compare(vab1))
                    return true;
            }
            return false;
        });
    }
    public int FindKeyIndex(TKey key)
    {
        return Lock(this, () =>
        {
            return _keys.FindEntry(key);
        });
    }
    public KeyValuePair<TKey, TValue>[] ToArray()
    {
        return Lock(this, () =>
        {
            var array = new KeyValuePair<TKey, TValue>[Count];
            var idx   = 0;
            foreach (var k in _keys)
                if (_keys.FindEntry(k) != -1)
                {
                    var v = _values[_keys.Position];
                    array[idx] = new KeyValuePair<TKey, TValue>(k, v);
                    idx++;
                }
            return array;
        });
    }
    public void Clear()
    {
        Lock(this, () =>
        {
            _keys   = new MSet15<TKey>(_keys.Slots.Length);
            _values = new TValue[_keys.Slots.Length];
        });
    }
}
[SecuritySafeCritical]
    public static unsafe bool Compare(this byte[] a1, byte[] a2)
    {
        if (a1 == null && a2 == null)
            return true;
        if (a1 == null || a2 == null || a1.Length != a2.Length)
            return false;
        fixed (byte* p1 = a1, p2 = a2)
        {
            var   Len = a1.Length;
            byte* x1  = p1, x2 = p2;
            while (Len > 7)
            {
                if (*(long*) x2 != *(long*) x1)
                    return false;
                x1  += 8;
                x2  += 8;
                Len -= 8;
            }
            switch (Len % 8)
            {
                case 0:
                    break;
                case 7:
                    if (*(int*) x2 != *(int*) x1)
                        return false;
                    x1 += 4;
                    x2 += 4;
                    if (*(short*) x2 != *(short*) x1)
                        return false;
                    x1 += 2;
                    x2 += 2;
                    if (*x2 != *x1)
                        return false;
                    break;
                case 6:
                    if (*(int*) x2 != *(int*) x1)
                        return false;
                    x1 += 4;
                    x2 += 4;
                    if (*(short*) x2 != *(short*) x1)
                        return false;
                    break;
                case 5:
                    if (*(int*) x2 != *(int*) x1)
                        return false;
                    x1 += 4;
                    x2 += 4;
                    if (*x2 != *x1)
                        return false;
                    break;
                case 4:
                    if (*(int*) x2 != *(int*) x1)
                        return false;
                    break;
                case 3:
                    if (*(short*) x2 != *(short*) x1)
                        return false;
                    x1 += 2;
                    x2 += 2;
                    if (*x2 != *x1)
                        return false;
                    break;
                case 2:
                    if (*(short*) x2 != *(short*) x1)
                        return false;
                    break;
                case 1:
                    if (*x2 != *x1)
                        return false;
                    break;
            }
            return true;
        }
    }

SessionId.cs

Session Id Class Hash Reduction Mapping

using System;
using System.Numerics;
using System.Security.Cryptography;
public class SessionId
{
    private readonly SHA512Managed                _hash = new SHA512Managed();
    private readonly AcDictionary<byte[], byte[]> map   = new AcDictionary<byte[], byte[]>(1024, new ArrayComparer());
    public byte[] GetUniqueSessionId<T>(T obj, int bitWidth)
    {
        if (bitWidth < 32 || bitWidth > 256)
            throw new ArgumentException($"Bit Width {bitWidth} must be between 32 and 256.");
        var bytes = obj.GetBytes();
        var hash  = _hash.ComputeHash(bytes, 0, bytes.Length);
        map.Add(hash, bytes);
        var ba = (byte[]) map.FindKeyIndex(hash).GetBytes().Clone();
        return ba.SubArray(0, bitWidth >> 3);
    }
    public int GetUniqueSessionIntId<T>(T obj)
    {
        var bytes = obj.GetBytes();
        var hash  = _hash.ComputeHash(bytes, 0, bytes.Length);
        map.Add(hash, bytes);
        return map.FindKeyIndex(hash);
    }
    public BigInteger PermutationWithRepetition(BigInteger n, int r)
    {
        if (r == BigInteger.Zero)
            return BigInteger.Zero;
        if (n == BigInteger.Zero)
            return BigInteger.Zero;
        return BigInteger.Pow(n, r) - 1;
    }
}

EntropyEx.cs

Generic Entropy Class

using System;
using System.Collections.Generic;
using System.Text;
public class EntropyEx<T>
{
    private const    double             NaturalLogOfTwo = 0.69314718055994530941723212145818;
    private readonly Dictionary<T, int> _histograpm     = new Dictionary<T, int>();
    private          bool               _histograpmStatus;
    private readonly int                _size;
    public EntropyEx()
    {
        _histograpm.Clear();
        _histograpmStatus = false;
        _size             = GetSize();
    }
    public double Entropy(string str)
    {
        var s = str.GetBytes(Encoding.Default);
        var histograpmL = new Dictionary<byte, int>();
        foreach (var c in s)
            if (!histograpmL.ContainsKey(c))
                histograpmL.Add(c, 1);
            else
                histograpmL[c] += 1;
        var e = 0.0;
        foreach (var v in histograpmL.Values)
        {
            if (v <= 0)
                continue;
            var r = v             / (double)s.Length;
            e -= r * (Math.Log(r) / NaturalLogOfTwo);
        }
        return e / 8 * 100.0;
    }
    public double Entropy(T[] s)
    {
        if (_histograpmStatus)
        {
            _histograpm.Clear();
            _histograpmStatus = false;
        }
        foreach (var c in s)
            if (!_histograpm.ContainsKey(c))
                _histograpm.Add(c, 1);
            else
                _histograpm[c] += 1;
        _histograpmStatus = true;
        var e = 0.0;
        foreach (var v in _histograpm.Values)
        {
            if (v <= 0)
                continue;
            var r = v             / (double) s.Length;
            e -= r * (Math.Log(r) / NaturalLogOfTwo);
        }
        return e / _size * 100.0;
    }
    private byte[] ConvertTypeByteArray(T[] ia)
    {
        switch (Type.GetTypeCode(typeof(T)))
        {
            case TypeCode.Boolean:
                break;
            case TypeCode.Char:
                break;
            case TypeCode.SByte:
                break;
            case TypeCode.Byte:
                break;
            case TypeCode.Int16:
                break;
            case TypeCode.UInt16:
                break;
            case TypeCode.Int32:
                break;
            case TypeCode.UInt32:
                break;
            case TypeCode.Single:
                break;
            case TypeCode.String:
                break;
            case TypeCode.Decimal:
                break;
            case TypeCode.Int64:
                break;
            case TypeCode.UInt64:
                break;
            case TypeCode.Double:
                break;
            case TypeCode.DateTime:
                break;
            default:
                throw new ArgumentException("Type is not a valid primitive.");
        }
        return ia.GetBytes();
    }
    private int GetSize()
    {
        var size = 0;
        switch (Type.GetTypeCode(typeof(T)))
        {
            case TypeCode.Boolean:
                size = 1;
                break;
            case TypeCode.Char:
                size = 16;
                break;
            case TypeCode.SByte:
                size = 8;
                break;
            case TypeCode.Byte:
                size = 8;
                break;
            case TypeCode.Int16:
                size = 16;
                break;
            case TypeCode.UInt16:
                size = 16;
                break;
            case TypeCode.Int32:
                size = 32;
                break;
            case TypeCode.UInt32:
                size = 32;
                break;
            case TypeCode.Single:
                size = 32;
                break;
            case TypeCode.String:
                size = 32;
                break;
            case TypeCode.Decimal:
                size = 192;
                break;
            case TypeCode.Int64:
                size = 64;
                break;
            case TypeCode.UInt64:
                size = 64;
                break;
            case TypeCode.Double:
                size = 64;
                break;
            case TypeCode.DateTime:
                size = 64;
                break;
            default:
                throw new ArgumentException("Type is not a valid primitive within this context.");
        }
        return size;
    }
}

MemoryStreamReader.cs

MemoryStream Reader Class

using System;
using System.Collections.Generic;
using System.IO;
using System.Numerics;
using System.Text;
public class MemoryStreamReader : IDisposable
{
    public static string[] Readerwritertypes =
    {
        "BOOLN       ", //0
        "CHAR        ", //1
        "BYTE        ", //2
        "SBYTE       ", //3
        "SHORT       ", //4
        "USHORT      ", //5
        "INTEGER     ", //6
        "UINTEGER    ", //7
        "LONG        ", //8
        "ULONG       ", //9
        "STRING      ", //10
        "FLOAT       ", //11
        "DOUBLE      ", //12
        "DECIMAL     ", //13
        "BOOLARRY    ", //14
        "CHARARRY    ", //15
        "BYTEARRY    ", //16
        "SBYTEARRY   ", //17
        "SHORTARRY   ", //18
        "USHORTARRY  ", //19
        "INTARRY     ", //20
        "UINTARRY    ", //21
        "LONGARRY    ", //22
        "ULONGARRY   ", //23
        "STRINGARRY  ", //24
        "FLOATARRY   ", //25
        "DOUBLEARRY  ", //26
        "DECIMALARRY ", //27
        "BIGINTEGER  ", //28
        "BIGINTARRY  ", //29
        "BIGRATIONAL ", //30
        "BIGRATARRY  ", //31
        "DATETIME    ", //32
        "DATETIMEARRY", //33
        "REFVALUETYPE"  //34
    };
    private readonly Decoder  _decoder;
    private readonly Encoder  _encoder;
    private readonly Encoding _encoding;
    public MemoryStreamReader() : this(null, new UTF8Encoding(false, true))
    {
    }
    public MemoryStreamReader(Stream input) : this(input, new UTF8Encoding())
    {
    }
    public MemoryStreamReader(Stream input, Encoding encoding)
    {
        if (input == null)
        {
            BaseStream = new MemoryStream();
        }
        else
        {
            BaseStream          = input;
            BaseStream.Position = 0;
        }
        if (encoding == null)
            _encoding = new UTF8Encoding(false, true);
        else
            _encoding = encoding;
        _encoder = _encoding.GetEncoder();
        _decoder = _encoding.GetDecoder();
    }
    public Stream BaseStream
    {
        get;
        set;
    }
    private bool IsUnicode => _encoding is UnicodeEncoding;
    public void Dispose()
    {
        Dispose(true);
    }
    public void Close()
    {
        Dispose(true);
    }
    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
            BaseStream.Close();
        BaseStream = null;
    }
    public IEnumerable<object> GetDataList()
    {
        var list = new List<object>();
        while (true)
        {
            var obj = Read();
            if (obj == null)
                break;
            list.Add(obj);
        }
        return list;
    }
    public KeyValuePair<string, object>[] GetDataKP()
    {
        var kpl = new List<KeyValuePair<string, object>>();
        while (true)
        {
            var obj = Read();
            if (obj == null)
                break;
            kpl.Add(new KeyValuePair<string, object>(obj.GetType().Name, obj));
        }
        return kpl.ToArray();
    }
    public object Read()
    {
        var head = GetNextHeader();
        if (head == null)
            return null;
        if (head.IndexOf(Readerwritertypes[0], StringComparison.Ordinal) != -1)
        {
            var vbuf = new byte[1];
            BaseStream.Read(vbuf, 0, 1);
            var obj = BitConverter.ToBoolean(vbuf, 0);
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[1], StringComparison.Ordinal) != -1)
        {
            var cl   = IsUnicode ? 2 : 1;
            var vbuf = new byte[cl];
            BaseStream.Read(vbuf, 0, cl);
            var obj = _encoding.GetString(vbuf).ToCharArray()[0];
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[2], StringComparison.Ordinal) != -1)
        {
            var vbuf = new byte[1];
            BaseStream.Read(vbuf, 0, 1);
            return vbuf;
        }
        if (head.IndexOf(Readerwritertypes[3], StringComparison.Ordinal) != -1)
        {
            var vbuf = new byte[1];
            BaseStream.Read(vbuf, 0, 1);
            return (sbyte) vbuf[0];
        }
        if (head.IndexOf(Readerwritertypes[4], StringComparison.Ordinal) != -1)
        {
            var vbuf = new byte[2];
            BaseStream.Read(vbuf, 0, 2);
            var obj = BitConverter.ToInt16(vbuf, 0);
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[5], StringComparison.Ordinal) != -1)
        {
            var vbuf = new byte[2];
            BaseStream.Read(vbuf, 0, 2);
            var obj = BitConverter.ToUInt16(vbuf, 0);
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[6], StringComparison.Ordinal) != -1)
        {
            var vbuf = new byte[4];
            BaseStream.Read(vbuf, 0, 4);
            var obj = BitConverter.ToInt32(vbuf, 0);
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[7], StringComparison.Ordinal) != -1)
        {
            var vbuf = new byte[4];
            BaseStream.Read(vbuf, 0, 4);
            var obj = BitConverter.ToUInt32(vbuf, 0);
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[8], StringComparison.Ordinal) != -1)
        {
            var vbuf = new byte[8];
            BaseStream.Read(vbuf, 0, 8);
            var obj = BitConverter.ToInt64(vbuf, 0);
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[9], StringComparison.Ordinal) != -1)
        {
            var vbuf = new byte[8];
            BaseStream.Read(vbuf, 0, 8);
            var obj = BitConverter.ToUInt64(vbuf, 0);
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[10], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = _encoding.GetString(vbuf);
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[11], StringComparison.Ordinal) != -1)
        {
            var vbuf = new byte[4];
            BaseStream.Read(vbuf, 0, 4);
            var obj = BitConverter.ToSingle(vbuf, 0);
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[12], StringComparison.Ordinal) != -1)
        {
            var vbuf = new byte[8];
            BaseStream.Read(vbuf, 0, 8);
            var obj = BitConverter.ToDouble(vbuf, 0);
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[13], StringComparison.Ordinal) != -1)
        {
            var vbuf = new byte[16];
            BaseStream.Read(vbuf, 0, 16);
            var obj = vbuf.ToDecimal();
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[28], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = new BigInteger(vbuf);
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[30], StringComparison.Ordinal) != -1)
        {
            var nlbuf = new byte[4];
            BaseStream.Read(nlbuf, 0, 4);
            var nlen = nlbuf.ToInt();
            var nbuf = new byte[nlen];
            BaseStream.Read(nbuf, 0, nlen);
            var dlbuf = new byte[4];
            BaseStream.Read(dlbuf, 0, 4);
            var dlen = dlbuf.ToInt();
            var dbuf = new byte[dlen];
            BaseStream.Read(dbuf, 0, dlen);
            var obj = new BigRational(new BigInteger(nbuf), new BigInteger(dbuf));
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[32], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var ll  = BitConverter.ToInt64(vbuf, 0);
            var obj = DateTime.FromBinary(ll);
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[34], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = vbuf.ByteArrayToObject();
            return obj;
        }

        ////start the array section tomorrow ** MJS ** Snow tonight and tomorrow 9 inches? BULL maybe 4 ** MJS ** 01/15/21
        if (head.IndexOf(Readerwritertypes[14], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = vbuf.ToBooleanArray();
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[15], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = _encoding.GetString(vbuf).ToCharArray();
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[16], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            return vbuf;
        }
        if (head.IndexOf(Readerwritertypes[17], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            return (sbyte[]) vbuf.Clone();
        }
        if (head.IndexOf(Readerwritertypes[18], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = vbuf.ToShortArray();
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[19], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = vbuf.ToUShortArray();
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[20], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = vbuf.ToIntArray();
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[21], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = vbuf.ToUIntArray();
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[22], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = vbuf.ToLongArray();
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[23], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = vbuf.ToULongArray();
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[23], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = vbuf.ToULongArray();
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[24], StringComparison.Ordinal) != -1)
        {
            var albuf = new byte[4];
            BaseStream.Read(albuf, 0, 4);
            var alen = albuf.ToInt();
            var rstr = new string[alen];
            for (var i = 0; i < alen; ++i)
            {
                var slbuf = new byte[4];
                BaseStream.Read(slbuf, 0, 4);
                var slen = slbuf.ToInt();
                var sbuf = new byte[slen];
                var str  = _encoding.GetString(sbuf, 0, slen);
                rstr[i] = str;
            }
            return rstr;
        }
        if (head.IndexOf(Readerwritertypes[25], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = vbuf.ToFloatArray();
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[26], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = vbuf.ToDoubleArray();
            return obj;
        }
        if (head.IndexOf(Readerwritertypes[27], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var vbuf = new byte[len];
            BaseStream.Read(vbuf, 0, len);
            var obj = vbuf.ToDecimalArray();
            return obj;
        }

        if (head.IndexOf(Readerwritertypes[29], StringComparison.Ordinal) != -1)
        {
            var lbuf = new byte[4];
            BaseStream.Read(lbuf, 0, 4);
            var len  = lbuf.ToInt();
            var objr = new BigInteger[len];

            for (var i = 0; i < len; ++i)
            {
                var ilb = new byte[4];
                BaseStream.Read(ilb, 0, 4);
                var blen = lbuf.ToInt();


                var vbuf = new byte[blen];
                BaseStream.Read(vbuf, 0, len);
                objr[i] = new BigInteger(vbuf);
            }
            return objr;
        }
        return null;
    }
    private string GetNextHeader()
    {
        if (PeekChar() != -1)
        {
            var buf = new byte[Readerwritertypes[0].Length];
            BaseStream.Read(buf, 0, buf.Length);
            var head = _encoding.GetString(buf);
            return head;
        }
        return null;
    }
    public int PeekChar()
    {
        if (BaseStream == null)
            throw new Exception("Input Stream is Null");
        if (!BaseStream.CanSeek)
            return -1;
        var position = BaseStream.Position;
        var coec     = ReadOne();
        BaseStream.Position = position;
        return coec;
    }
    private int ReadOne()
    {
        if (BaseStream == null)
            throw new Exception("Input Stream is Null");
        var bytes = new byte[IsUnicode ? 2 : 1];
        var sc    = new char[1];
        var br    = _decoder.GetChars(bytes, 0, bytes.Length, sc, 0);
        return br == 0 ? -1 : sc[0];
    }
}