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];
    }
}

MemoryStreamWriter.cs

MemoryStream Writer Class

using System;
using System.Collections.Generic;
using System.IO;
using System.Numerics;
using System.Reflection;
using System.Text;
public class MemoryStreamWriter : 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 Encoder  _encoder;
    private readonly Encoding _encoding;
    public MemoryStreamWriter() : this(null, new UTF8Encoding(false, true))
    {
    }
    public MemoryStreamWriter(Stream input) : this(input, new UTF8Encoding())
    {
    }
    public MemoryStreamWriter(Stream input, Encoding encoding)
    {
        if (input == null)
            BaseStream = new MemoryStream();
        else
            BaseStream = input;
        _encoding = encoding;
        _encoder  = _encoding.GetEncoder();
    }
    public Stream BaseStream
    {
        get;
    }
    public static int PrimitiveOverHead => sizeof(int);
    public static int ArrayOverHead     => sizeof(int) * 2;
    public void Dispose()
    {
        if (BaseStream == null) return;


        if (BaseStream.CanWrite)
        {
            BaseStream.Flush();
        }
        BaseStream.Dispose();
    }
    public long Seek(int offset, SeekOrigin origin)
    {
        return BaseStream.Seek(offset, origin);
    }
    public void SetData(IEnumerable<object> obja)
    {
        if (obja != null)
            foreach (var o in obja)
                Write(o);
    }
    public void Write(object obj)
    {
        var ltype = obj.GetType();
        switch (ltype.Name.Trim('[', ']'))
        {
            case "Byte":
                if (!ltype.IsArray)
                    Write((byte) obj);
                else
                    Write((byte[]) obj);
                return;
            case "Boolean":
                if (!ltype.IsArray)
                    Write((bool) obj);
                else
                    Write((bool[]) obj);
                return;
            case "SByte":
                if (!ltype.IsArray)
                    Write((sbyte) obj);
                else
                    Write((sbyte[]) obj);
                return;
            case "Char":
                if (!ltype.IsArray)
                    Write((char) obj);
                else
                    Write((char[]) obj);
                return;
            case "Int16":
                if (!ltype.IsArray)
                    Write((short) obj);
                else
                    Write((short[]) obj);
                return;
            case "UInt16":
                if (!ltype.IsArray)
                    Write((ushort) obj);
                else
                    Write((ushort[]) obj);
                return;
            case "Int32":
                if (!ltype.IsArray)
                    Write((int) obj);
                else
                    Write((int[]) obj);
                return;
            case "UInt32":
                if (!ltype.IsArray)
                    Write((uint) obj);
                else
                    Write((uint[]) obj);
                return;
            case "Int64":
                if (!ltype.IsArray)
                    Write((long) obj);
                else
                    Write((long[]) obj);
                return;
            case "UInt64":
                if (!ltype.IsArray)
                    Write((ulong) obj);
                else
                    Write((ulong[]) obj);
                return;
            case "Single":
                if (!ltype.IsArray)
                    Write((float) obj);
                else
                    Write((float[]) obj);
                return;
            case "Double":
                if (!ltype.IsArray)
                    Write((double) obj);
                else
                    Write((double[]) obj);
                return;
            case "String":
                if (!ltype.IsArray)
                    Write((string) obj);
                else
                    Write((string[]) obj);
                return;
            case "Decimal":
                if (!ltype.IsArray)
                    Write((decimal) obj);
                else
                    Write((decimal[]) obj);
                return;
            case "DateTime":
                if (!ltype.IsArray)
                    Write((DateTime) obj);
                else
                    Write((DateTime[]) obj);
                return;

            case "BigInteger":
                if (!ltype.IsArray)
                    Write((BigInteger)obj);
                else
                    Write((BigInteger[])obj);
                return;
        }
        if (ltype.IsSerializable)
        {
            var flds = ltype.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy);
            if (flds.Length > 0)
            {
                BaseStream.Write(Readerwritertypes[34].GetBytes(), 0, 4);
                var buf = obj.ObjectToByteArray();
                BaseStream.Write(buf.Length.GetBytes(), 0, 4);
                BaseStream.Write(buf,                   0, buf.Length);
                return;
            }
            throw new Exception("Serializable Value and Reference Types, no meaningful data can be found.");
        }
        throw new Exception("Unsupported Type.");
    }
    private void Write(bool value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[0]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf, 0, buf.Length);
    }
    private unsafe void Write(char value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[1]);
        BaseStream.Write(head, 0, head.Length);
        var buf = new byte[2];
        int len;
        fixed (byte* bytes2 = buf)
        {
            len = _encoder.GetBytes(&value, 1, bytes2, buf.Length, true);
        }
        BaseStream.Write(buf, 0, len);
    }
    private void Write(byte value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[2]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf, 0, buf.Length);
    }
    private void Write(sbyte value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[3]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf, 0, buf.Length);
    }
    private void Write(short value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[4]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf, 0, buf.Length);
    }
    private void Write(ushort value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[5]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf, 0, buf.Length);
    }
    private void Write(int value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[6]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf, 0, buf.Length);
    }
    private void Write(uint value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[7]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf, 0, buf.Length);
    }
    private void Write(long value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[8]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf, 0, buf.Length);
    }
    private void Write(ulong value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[9]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf, 0, buf.Length);
    }
    private void Write(string value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[10]);
        BaseStream.Write(head, 0, head.Length);
        var count = _encoding.GetByteCount(value);
        var cbuf  = count.GetBytes();
        BaseStream.Write(cbuf, 0, cbuf.Length);
        var LBuffer = new byte[count];
        _encoding.GetBytes(value, 0, value.Length, LBuffer, 0);
        BaseStream.Write(LBuffer, 0, LBuffer.Length);
    }
    private void Write(float value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[11]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf, 0, buf.Length);
    }
    private void Write(double value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[12]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf, 0, buf.Length);
    }
    private void Write(decimal value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[13]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf, 0, buf.Length);
    }
    private void Write(BigInteger value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[28]);
        BaseStream.Write(head, 0, head.Length);
        var buf  = value.ToByteArray();
        var lbuf = buf.Length;
        var labb = lbuf.GetBytes();
        BaseStream.Write(labb, 0, labb.Length);
        BaseStream.Write(buf,  0, buf.Length);
    }
    private void Write(BigRational value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[30]);
        BaseStream.Write(head, 0, head.Length);
        var Num  = value.Numerator.ToByteArray();
        var lnum = Num.Length;
        var lnab = lnum.GetBytes();
        BaseStream.Write(lnab, 0, lnab.Length);
        BaseStream.Write(Num,  0, Num.Length);
        var Den  = value.Denominator.ToByteArray();
        var lden = Den.Length;
        var ldab = lden.GetBytes();
        BaseStream.Write(ldab, 0, ldab.Length);
        BaseStream.Write(Den,  0, Den.Length);
    }
    private void Write(DateTime value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[32]);
        BaseStream.Write(head, 0, head.Length);
        var asl   = value.ToBinary();
        var vbuf  = BitConverter.GetBytes(asl);
        var lbuf  = vbuf.Length;
        var lbufb = lbuf.GetBytes();
        BaseStream.Write(lbufb, 0, lbufb.Length);
        BaseStream.Write(vbuf,  0, vbuf.Length);
    }
    private void Write(bool[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[14]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf.Length.GetBytes(), 0, 4);
        BaseStream.Write(buf,                   0, buf.Length);
    }
    private void Write(char[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[15]);
        BaseStream.Write(head, 0, head.Length);
        var bytes = _encoding.GetBytes(value, 0, value.Length);
        var bbuf  = bytes.Length.GetBytes();
        BaseStream.Write(bbuf,  0, bbuf.Length);
        BaseStream.Write(bytes, 0, bytes.Length);
    }
    private void Write(byte[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[16]);
        BaseStream.Write(head,                    0, head.Length);
        BaseStream.Write(value.Length.GetBytes(), 0, 4);
        BaseStream.Write(value,                   0, value.Length);
    }
    private void Write(sbyte[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[17]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf.Length.GetBytes(), 0, 4);
        BaseStream.Write(buf,                   0, buf.Length);
    }
    private void Write(short[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[18]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf.Length.GetBytes(), 0, 4);
        BaseStream.Write(buf,                   0, buf.Length);
    }
    private void Write(ushort[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[19]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf.Length.GetBytes(), 0, 4);
        BaseStream.Write(buf,                   0, buf.Length);
    }
    private void Write(int[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[20]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf.Length.GetBytes(), 0, 4);
        BaseStream.Write(buf,                   0, buf.Length);
    }
    private void Write(uint[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[21]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf.Length.GetBytes(), 0, 4);
        BaseStream.Write(buf,                   0, buf.Length);
    }
    private void Write(long[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[22]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf.Length.GetBytes(), 0, 4);
        BaseStream.Write(buf,                   0, buf.Length);
    }
    private void Write(ulong[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[23]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf.Length.GetBytes(), 0, 4);
        BaseStream.Write(buf,                   0, buf.Length);
    }
    private void Write(string[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[24]);
        BaseStream.Write(head,                    0, head.Length);
        BaseStream.Write(value.Length.GetBytes(), 0, 4);
        foreach (var v in value)
        {
            var count = _encoding.GetByteCount(v);
            var cbuf  = count.GetBytes();
            BaseStream.Write(cbuf, 0, cbuf.Length);
            var LBuffer = new byte[count];
            _encoding.GetBytes(v, 0, v.Length, LBuffer, 0);
            BaseStream.Write(LBuffer, 0, LBuffer.Length);
        }
    }
    private void Write(float[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[25]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf.Length.GetBytes(), 0, 4);
        BaseStream.Write(buf,                   0, buf.Length);
    }
    private void Write(double[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[26]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf.Length.GetBytes(), 0, 4);
        BaseStream.Write(buf,                   0, buf.Length);
    }
    private void Write(decimal[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[27]);
        BaseStream.Write(head, 0, head.Length);
        var buf = value.GetBytes();
        BaseStream.Write(buf.Length.GetBytes(), 0, 4);
        BaseStream.Write(buf,                   0, buf.Length);
    }
    private void Write(BigInteger[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[29]);
        BaseStream.Write(head, 0, head.Length);
        var larr   = value.Length;
        var larrab = larr.GetBytes();
        BaseStream.Write(larrab, 0, larrab.Length);
        foreach (var v in value)
        {
            var buf = v.GetBytes();
            BaseStream.Write(buf.Length.GetBytes(), 0, 4);
            BaseStream.Write(buf,                   0, buf.Length);
        }
    }
    private void Write(BigRational[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[31]);
        BaseStream.Write(head, 0, head.Length);
        foreach (var v in value)
        {
            var buf = v.GetBytes();
            BaseStream.Write(buf.Length.GetBytes(), 0, 4);
            BaseStream.Write(buf,                   0, buf.Length);
        }
    }
    private void Write(DateTime[] value)
    {
        var head = _encoding.GetBytes(Readerwritertypes[33]);
        BaseStream.Write(head, 0, head.Length);
        foreach (var v in value)
        {
            var buf = v.Ticks.GetBytes();
            BaseStream.Write(buf.Length.GetBytes(), 0, 4);
            BaseStream.Write(buf,                   0, buf.Length);
        }
    }
}

RawMemoryStreamWriter.cs

Writes Raw Interpreted Primitive Values to a Memory Stream

It is not possible to recode the raw data stream once encoded, thus there is no RawMemoryStreamReader.

using System;
using System.IO;
using System.Security;
using System.Text;
[Serializable]
public class RawMemoryStreamWriter : IDisposable
{
    private readonly Encoder      _encoder;
    private readonly Encoding     _encoding;
    private          byte[]       _buffer;
    private          MemoryStream _outStream;
    public RawMemoryStreamWriter()
    {
        _outStream = new MemoryStream();
        _buffer    = new byte[8];
        _encoding  = new UTF8Encoding(false, true);
        _encoder   = _encoding.GetEncoder();
    }
    public MemoryStream BaseStream
    {
        get
        {
            Flush();
            return _outStream;
        }
    }
    public void Dispose()
    {
        Dispose(true);
    }
    public void Close()
    {
        Dispose(true);
    }
    protected void Dispose(bool disposing)
    {
        if (!disposing)
            return;
        _outStream.Close();
    }
    public void Flush()
    {
        _outStream.Flush();
    }
    public long Seek(int offset, SeekOrigin origin)
    {
        return _outStream.Seek(offset, origin);
    }
    public void Write(object obj)
    {
        var ltype = obj.GetType();
        switch (ltype.Name.Trim('[', ']'))
        {
            case "Byte":
                if (!ltype.IsArray)
                    Write((byte) obj);
                else
                    Write((byte[]) obj);
                break;
            case "Boolean":
                if (!ltype.IsArray)
                    Write((bool) obj);
                else
                    Write((bool[]) obj);
                break;
            case "SByte":
                if (!ltype.IsArray)
                    Write((sbyte) obj);
                else
                    Write((sbyte[]) obj);
                break;
            case "Char":
                if (!ltype.IsArray)
                    Write((char) obj);
                else
                    Write((char[]) obj);
                break;
            case "Int16":
                if (!ltype.IsArray)
                    Write((short) obj);
                else
                    Write((short[]) obj);
                break;
            case "UInt16":
                if (!ltype.IsArray)
                    Write((ushort) obj);
                else
                    Write((ushort[]) obj);
                break;
            case "Int32":
                if (!ltype.IsArray)
                    Write((int) obj);
                else
                    Write((int[]) obj);
                break;
            case "UInt32":
                if (!ltype.IsArray)
                    Write((uint) obj);
                else
                    Write((uint[]) obj);
                break;
            case "Int64":
                if (!ltype.IsArray)
                    Write((long) obj);
                else
                    Write((long[]) obj);
                break;
            case "UInt64":
                if (!ltype.IsArray)
                    Write((ulong) obj);
                else
                    Write((ulong[]) obj);
                break;
            case "Single":
                if (!ltype.IsArray)
                    Write((float) obj);
                else
                    Write((float[]) obj);
                break;
            case "Double":
                if (!ltype.IsArray)
                    Write((double) obj);
                else
                    Write((double[]) obj);
                break;
            case "String":
                if (!ltype.IsArray)
                    Write((string) obj);
                else
                    Write((string[]) obj);
                break;
            case "Decimal":
                if (!ltype.IsArray)
                    Write((decimal) obj);
                else
                    Write((decimal[]) obj);
                break;
            case "DateTime":
                if (!ltype.IsArray)
                    Write((DateTime) obj);
                else
                    Write((DateTime[]) obj);
                break;
        }
    }
    private void Write(bool value)
    {
        _buffer[0] = value ? (byte) 1 : (byte) 0;
        _outStream.Write(_buffer, 0, 1);
    }
    private void Write(bool[] value)
    {
        for (var i = 0; i < value.Length; ++i)
        {
            _buffer[0] = value[i] ? (byte) 1 : (byte) 0;
            _outStream.Write(_buffer, 0, 1);
        }
    }
    private void Write(byte value)
    {
        _outStream.WriteByte(value);
    }
    private void Write(sbyte value)
    {
        _outStream.WriteByte((byte) value);
    }
    private void Write(sbyte[] value)
    {
        for (var i = 0; i < value.Length; ++i)
            _outStream.WriteByte((byte) value[i]);
    }
    private void Write(byte[] buffer)
    {
        if (buffer == null)
            throw new ArgumentNullException(nameof(buffer));
        _outStream.Write(buffer, 0, buffer.Length);
    }
    private void Write(byte[] buffer, int index, int count)
    {
        _outStream.Write(buffer, index, count);
    }
    [SecuritySafeCritical]
    private unsafe void Write(char ch)
    {
        int blen;
        fixed (byte* bytes = _buffer)
        {
            blen = _encoder.GetBytes(&ch, 1, bytes, _buffer.Length, true);
        }
        _outStream.Write(_buffer, 0, blen);
    }
    private void Write(char[] chars)
    {
        if (chars == null)
            throw new ArgumentNullException(nameof(chars));
        var bytes = _encoding.GetBytes(chars, 0, chars.Length);
        _outStream.Write(bytes, 0, bytes.Length);
    }
    private void Write(char[] chars, int index, int count)
    {
        var bytes = _encoding.GetBytes(chars, index, count);
        _outStream.Write(bytes, 0, bytes.Length);
    }
    [SecuritySafeCritical]
    private unsafe void Write(double value)
    {
        var num = (ulong) *(long*) &value;
        _buffer[0] = (byte) num;
        _buffer[1] = (byte) (num >> 8);
        _buffer[2] = (byte) (num >> 16);
        _buffer[3] = (byte) (num >> 24);
        _buffer[4] = (byte) (num >> 32);
        _buffer[5] = (byte) (num >> 40);
        _buffer[6] = (byte) (num >> 48);
        _buffer[7] = (byte) (num >> 56);
        _outStream.Write(_buffer, 0, 8);
    }
    private void Write(double[] value)
    {
        for (var i = 0; i < value.Length; ++i)
            Write(value[i]);
    }
    private void Write(decimal value)
    {
        var bits  = decimal.GetBits(value);
        var lo    = bits[0];
        var mid   = bits[1];
        var hi    = bits[2];
        var flags = bits[3];
        _buffer[0]  = (byte) lo;
        _buffer[1]  = (byte) (lo >> 8);
        _buffer[2]  = (byte) (lo >> 16);
        _buffer[3]  = (byte) (lo >> 24);
        _buffer[4]  = (byte) mid;
        _buffer[5]  = (byte) (mid >> 8);
        _buffer[6]  = (byte) (mid >> 16);
        _buffer[7]  = (byte) (mid >> 24);
        _buffer[8]  = (byte) hi;
        _buffer[9]  = (byte) (hi >> 8);
        _buffer[10] = (byte) (hi >> 16);
        _buffer[11] = (byte) (hi >> 24);
        _buffer[12] = (byte) flags;
        _buffer[13] = (byte) (flags >> 8);
        _buffer[14] = (byte) (flags >> 16);
        _buffer[15] = (byte) (flags >> 24);
        _outStream.Write(_buffer, 0, 16);
    }
    private void Write(decimal[] value)
    {
        for (var i = 0; i < value.Length; ++i)
            Write(value[i]);
    }
    private void Write(short value)
    {
        _buffer[0] = (byte) value;
        _buffer[1] = (byte) ((uint) value >> 8);
        _outStream.Write(_buffer, 0, 2);
    }
    private void Write(short[] value)
    {
        for (var i = 0; i < value.Length; ++i)
            Write(value[i]);
    }
    private void Write(ushort value)
    {
        _buffer[0] = (byte) value;
        _buffer[1] = (byte) ((uint) value >> 8);
        _outStream.Write(_buffer, 0, 2);
    }
    private void Write(ushort[] value)
    {
        for (var i = 0; i < value.Length; ++i)
            Write(value[i]);
    }
    private void Write(int value)
    {
        _buffer[0] = (byte) value;
        _buffer[1] = (byte) (value >> 8);
        _buffer[2] = (byte) (value >> 16);
        _buffer[3] = (byte) (value >> 24);
        _outStream.Write(_buffer, 0, 4);
    }
    private void Write(int[] value)
    {
        for (var i = 0; i < value.Length; ++i)
            Write(value[i]);
    }
    private void Write(uint value)
    {
        _buffer[0] = (byte) value;
        _buffer[1] = (byte) (value >> 8);
        _buffer[2] = (byte) (value >> 16);
        _buffer[3] = (byte) (value >> 24);
        _outStream.Write(_buffer, 0, 4);
    }
    private void Write(uint[] value)
    {
        for (var i = 0; i < value.Length; ++i)
            Write(value[i]);
    }
    private void Write(long value)
    {
        _buffer[0] = (byte) value;
        _buffer[1] = (byte) (value >> 8);
        _buffer[2] = (byte) (value >> 16);
        _buffer[3] = (byte) (value >> 24);
        _buffer[4] = (byte) (value >> 32);
        _buffer[5] = (byte) (value >> 40);
        _buffer[6] = (byte) (value >> 48);
        _buffer[7] = (byte) (value >> 56);
        _outStream.Write(_buffer, 0, 8);
    }
    private void Write(long[] value)
    {
        for (var i = 0; i < value.Length; ++i)
            Write(value[i]);
    }
    private void Write(ulong value)
    {
        _buffer[0] = (byte) value;
        _buffer[1] = (byte) (value >> 8);
        _buffer[2] = (byte) (value >> 16);
        _buffer[3] = (byte) (value >> 24);
        _buffer[4] = (byte) (value >> 32);
        _buffer[5] = (byte) (value >> 40);
        _buffer[6] = (byte) (value >> 48);
        _buffer[7] = (byte) (value >> 56);
        _outStream.Write(_buffer, 0, 8);
    }
    private void Write(ulong[] value)
    {
        for (var i = 0; i < value.Length; ++i)
            Write(value[i]);
    }
    [SecuritySafeCritical]
    private unsafe void Write(float value)
    {
        var num = *(uint*) &value;
        _buffer[0] = (byte) num;
        _buffer[1] = (byte) (num >> 8);
        _buffer[2] = (byte) (num >> 16);
        _buffer[3] = (byte) (num >> 24);
        _outStream.Write(_buffer, 0, 4);
    }
    private void Write(float[] value)
    {
        for (var i = 0; i < value.Length; ++i)
            Write(value[i]);
    }
    [SecuritySafeCritical]
    private void Write(string value)
    {
        int count;
        if (value != null)
            count = _encoding.GetByteCount(value);
        else
            throw new Exception("Value cannot be null");
        var LBuffer = new byte[count];
        _encoding.GetBytes(value, 0, value.Length, LBuffer, 0);
        _outStream.Write(LBuffer, 0, count);
    }
    private void Write(string[] value)
    {
        for (var i = 0; i < value.Length; ++i)
            Write(value[i]);
    }
    private unsafe void Write(DateTime value)
    {
        var numArray = new byte[8];
        fixed (byte* ptr = numArray)
        {
            *(long*) ptr = value.Ticks;
        }
        _buffer[0] = numArray[0];
        _buffer[1] = numArray[1];
        _buffer[2] = numArray[2];
        _buffer[3] = numArray[3];
        _buffer[4] = numArray[4];
        _buffer[5] = numArray[5];
        _buffer[6] = numArray[6];
        _buffer[7] = numArray[7];
        _outStream.Write(_buffer, 0, 8);
    }
    private void Write(DateTime[] value)
    {
        for (var i = 0; i < value.Length; ++i)
            Write(value[i]);
    }
}

RandomX.cs

A Fast Random Number Generator Based on BigInteger

using System;
using System.Numerics;
using System.Security.Cryptography;
public struct RandomX
{
    private readonly RNGCryptoServiceProvider _crng;
    private          int                      _maxByteWidth;
    private          int                      _bitWidth;
    public RandomX(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 char NextChar(char maxValue)
    {
        if (maxValue < 0)
            throw new ArgumentException("maxValue must be greater than zero.");
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 16)
            BitWidth = 16;
        return (char) (Sample() * maxValue);
    }
    public char NextChar(char minValue, char maxValue)
    {
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 16)
            BitWidth = 16;
        return (char) Next(minValue, maxValue);
    }
    public sbyte NextInt8()
    {
        if (Unsigned)
            Unsigned = false;
        if (_bitWidth < 8)
            BitWidth = 8;
        return (sbyte) Internal();
    }
    public sbyte NextInt8(sbyte maxValue)
    {
        if (maxValue < 0)
            throw new ArgumentException("maxValue must be greater than zero.");
        if (Unsigned)
            Unsigned = false;
        if (_bitWidth < 8)
            BitWidth = 8;
        return (sbyte) (Sample() * maxValue);
    }
    public sbyte NextInt8(sbyte minValue, sbyte maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (Unsigned)
            Unsigned = false;
        if (_bitWidth < 8)
            BitWidth = 8;
        return (sbyte) Next(minValue, maxValue);
    }
    public byte NextUInt8()
    {
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 8)
            BitWidth = 8;
        var n = Internal();
        return (byte) n;
    }
    public byte NextUInt8(byte maxValue)
    {
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 8)
            BitWidth = 8;
        return (byte) (Sample() * maxValue);
    }
    public byte NextUInt8(byte minValue, byte maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 8)
            BitWidth = 8;
        return (byte) Next(minValue, maxValue);
    }
    public short NextInt16()
    {
        if (_bitWidth < 16)
            BitWidth = 16;
        if (Unsigned)
            Unsigned = false;
        return (short) Internal();
    }
    public short NextInt16(short maxValue)
    {
        if (maxValue < 0)
            throw new ArgumentException("maxValue must be greater than zero.");
        if (Unsigned)
            Unsigned = false;
        if (_bitWidth < 16)
            BitWidth = 16;
        return (short) (Sample() * maxValue);
    }
    public short NextInt16(short minValue, short maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (Unsigned)
            Unsigned = false;
        if (_bitWidth < 16)
            BitWidth = 16;
        return (short) Next(minValue, maxValue);
    }
    public ushort NextUInt16()
    {
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 16)
            BitWidth = 16;
        return (ushort) Internal();
    }
    public ushort NextUInt16(ushort maxValue)
    {
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 16)
            BitWidth = 16;
        return (ushort) (Sample() * maxValue);
    }
    public ushort NextUInt16(ushort minValue, ushort maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 16)
            BitWidth = 16;
        return (ushort) Next(minValue, maxValue);
    }
    public int NextInt24()
    {
        BitWidth = 24;
        if (Unsigned)
            Unsigned = false;
        return (int) Internal();
    }
    public int NextInt24(int maxValue)
    {
        if (maxValue < 0)
            throw new ArgumentException("maxValue must be greater than zero.");
        if (Unsigned)
            Unsigned = false;
        BitWidth = 24;
        return (int) (Sample() * maxValue);
    }
    public int NextInt24(int minValue, int maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (Unsigned)
            Unsigned = false;
        BitWidth = 24;
        return (int) Next(minValue, maxValue);
    }
    public uint NextUInt24()
    {
        if (!Unsigned)
            Unsigned = true;
        BitWidth = 24;
        return (uint) Internal();
    }
    public uint NextUInt24(uint maxValue)
    {
        if (!Unsigned)
            Unsigned = true;
        BitWidth = 24;
        return (uint) (Sample() * maxValue);
    }
    public uint NextUInt24(uint minValue, uint maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (!Unsigned)
            Unsigned = true;
        BitWidth = 24;
        return (uint) Next(minValue, maxValue);
    }
    public uint NextUInt32()
    {
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 32)
            BitWidth = 32;
        return (uint) Internal();
    }
    public uint NextUInt32(uint maxValue)
    {
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 32)
            BitWidth = 32;
        return (uint) (Sample() * maxValue);
    }
    public uint NextUInt32(uint minValue, uint maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 32)
            BitWidth = 32;
        return (uint) Next(minValue, maxValue);
    }
    public int NextInt32()
    {
        if (Unsigned)
            Unsigned = false;
        if (_bitWidth < 32)
            BitWidth = 32;
        return (int) Internal();
    }
    public int NextInt32(int maxValue)
    {
        if (maxValue < 0)
            throw new ArgumentException("maxValue must be greater than zero.");
        if (Unsigned)
            Unsigned = false;
        if (_bitWidth < 32)
            BitWidth = 32;
        return (int) (Sample() * maxValue);
    }
    public int NextInt32(int minValue, int maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (Unsigned)
            Unsigned = false;
        if (_bitWidth < 32)
            BitWidth = 32;
        return (int) Next(minValue, maxValue);
    }
    public long NextUInt40()
    {
        if (!Unsigned)
            Unsigned = true;
        BitWidth = 40;
        return (long) Internal();
    }
    public long NextUInt40(long maxValue)
    {
        if (!Unsigned)
            Unsigned = true;
        BitWidth = 40;
        return (long) (Sample() * maxValue);
    }
    public long NextUInt40(long minValue, long maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (!Unsigned)
            Unsigned = true;
        BitWidth = 40;
        return (long) Next(minValue, maxValue);
    }
    public long NextInt40()
    {
        if (Unsigned)
            Unsigned = false;
        BitWidth = 40;
        return (long) Internal();
    }
    public long NextInt40(long maxValue)
    {
        if (maxValue < 0)
            throw new ArgumentException("maxValue must be greater than zero.");
        if (Unsigned)
            Unsigned = false;
        BitWidth = 40;
        return (long) (Sample() * maxValue);
    }
    public long NextInt40(long minValue, long maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (Unsigned)
            Unsigned = false;
        BitWidth = 40;
        return (long) Next(minValue, maxValue);
    }
    public ulong NextUInt48()
    {
        if (!Unsigned)
            Unsigned = true;
        BitWidth = 48;
        return (ulong) Internal();
    }
    public ulong NextUInt48(ulong maxValue)
    {
        if (!Unsigned)
            Unsigned = true;
        BitWidth = 48;
        return (ulong) (Sample() * maxValue);
    }
    public ulong NextUInt48(ulong minValue, ulong maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (!Unsigned)
            Unsigned = true;
        BitWidth = 48;
        return (ulong) Next(minValue, maxValue);
    }
    public long NextInt48()
    {
        if (Unsigned)
            Unsigned = false;
        BitWidth = 48;
        return (long) Internal();
    }
    public long NextInt48(long maxValue)
    {
        if (maxValue < 0)
            throw new ArgumentException("maxValue must be greater than zero.");
        if (Unsigned)
            Unsigned = false;
        BitWidth = 48;
        return (long) (Sample() * maxValue);
    }
    public ulong NextUInt56()
    {
        if (!Unsigned)
            Unsigned = true;
        BitWidth = 56;
        return (ulong) Internal();
    }
    public ulong NextUInt56(ulong maxValue)
    {
        if (!Unsigned)
            Unsigned = true;
        BitWidth = 56;
        return (ulong) (Sample() * maxValue);
    }
    public ulong NextUInt56(ulong minValue, ulong maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (!Unsigned)
            Unsigned = true;
        BitWidth = 56;
        return (uint) Next(minValue, maxValue);
    }
    public long NextInt56()
    {
        if (Unsigned)
            Unsigned = false;
        BitWidth = 56;
        return (long) Internal();
    }
    public long NextInt56(long maxValue)
    {
        if (maxValue < 0)
            throw new ArgumentException("maxValue must be greater than zero.");
        if (Unsigned)
            Unsigned = false;
        BitWidth = 56;
        return (long) (Sample() * maxValue);
    }
    public long NextInt56(long minValue, long maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (Unsigned)
            Unsigned = false;
        BitWidth = 48;
        return (long) Next(minValue, maxValue);
    }
    public long NextInt64()
    {
        if (Unsigned)
            Unsigned = false;
        if (_bitWidth < 64)
            BitWidth = 64;
        return (long) Internal();
    }
    public long NextInt64(long maxValue)
    {
        if (maxValue < 0)
            throw new ArgumentException("maxValue must be greater than zero.");
        if (Unsigned)
            Unsigned = false;
        if (_bitWidth < 64)
            BitWidth = 64;
        return (long) (Sample() * maxValue);
    }
    public long NextInt64(long minValue, long maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (Unsigned)
            Unsigned = false;
        if (_bitWidth < 64)
            BitWidth = 64;
        return (long) Next(minValue, maxValue);
    }
    public ulong NextUInt64()
    {
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 64)
            BitWidth = 64;
        return (ulong) Internal();
    }
    public ulong NextUInt64(ulong maxValue)
    {
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 64)
            BitWidth = 64;
        return (ulong) (Sample() * maxValue);
    }
    public ulong NextUInt64(ulong minValue, ulong maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        if (!Unsigned)
            Unsigned = true;
        if (_bitWidth < 64)
            BitWidth = 64;
        return (ulong) Next(minValue, maxValue);
    }
    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 UInt512 Next(UInt512 minValue, UInt512 maxValue)
    {
        if (minValue > maxValue)
            throw new ArgumentException("maxValue must be greater than or equal to minValue");
        var s = Sample();
        var f = (BigDecimal) ((BigInteger) maxValue - (BigInteger) minValue);
        return (BigInteger) (s * f);
    }
    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 BigRational(Internal(), Internal());
    }
    public decimal NextDecimal()
    {
        return new decimal(NextInt32(), NextInt32(), NextInt32(), NextBool(), NextUInt8(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 string GetRandomString(int minLen, int maxLen)
    {
        return minLen == maxLen ? new string(GetNextCharArray(minLen)) : new string(GetNextCharArray((int) NextUInt32((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;
        }
    }
}

FNV1a128b.cs

FNV1a Patterned 128Bit Hashing Algorithm using BigInteger

using System.Numerics;
using System.Security.Cryptography;
public class FNV1a128b : HashAlgorithm
{
    private readonly BigInteger K = "309485009821345068724781371".BigIntegerBase10();
    private readonly BigInteger M = "340282366920938463463374607431768211456".BigIntegerBase10();
    private          BigInteger _hash;
    private readonly BigInteger Seed = "144066263297769815596495629667062367629".BigIntegerBase10();
    public FNV1a128b()
    {
        _hash = Seed;
    }
    public FNV1a128b(BigInteger seed)
    {
        Seed  = seed;
        _hash = Seed;
    }
    public override int HashSize => 128;
    public override void Initialize()
    {
        _hash = Seed;
    }
    protected override void HashCore(byte[] bytes, int ibStart, int cbSize)
    {
        Hash128(bytes, ibStart, cbSize);
    }
    protected override byte[] HashFinal()
    {
        return _hash.ToByteArray();
    }
    private unsafe void Hash128(byte[] bytes, int ibStart, int cbSize)
    {
        fixed (byte* pb = bytes)
        {
            var np = pb + ibStart;
            for (; cbSize > 0; --cbSize, np++)
                _hash = ((_hash ^ *np) * K) % M;
        }
    }
}

GetBytesClass.cs

GetBytes Primitive, Serializable, Non-Serializable Arrays

Updated: Jan-13,2021

using System;
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;
public static class GetBytesClass
{
    private static readonly int                      _charSize = sizeof(char);
    private static readonly BinaryFormatter          Formatter = new BinaryFormatter();
    private static readonly MonitorActionFuncWrapper _maf      = new MonitorActionFuncWrapper();
    private static readonly SHA512Managed            _hash     = new SHA512Managed();
    private static readonly object                   _lo       = new object();
    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>
    ///     GetBytes central GetType takes 22 Nanoseconds per call
    /// </summary>
    [SecurityCritical]
    public static byte[] GetBytes(this object obj)
    {
        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 RawReferenceValueTypeObjectGetBytes(obj);
    }
    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 ((long) value).GetBytes();
    }
    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 GetBytes(value.Sign).Add(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 BigInteger(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;
    }
    /// <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 t = new[] {value[i], value[i + 1], value[i + 2], value[i + 3]};
            arr.Add(t.ToFloat());
        }
        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 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]
            };
            arr.Add(t.ToDouble());
        }
        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 byte[] RawReferenceValueTypeObjectGetBytes<T>(T obj)
    {
        var type  = obj.GetType();
        var infos = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy);
        if (infos.Length > 0)
            using (var ms = new RawMemoryStreamWriter())
            {
                foreach (var info in infos)
                {
                    var v = info.GetValue(obj);
                    if (v != null && !IsValidPrimitive(v.GetType()))
                    {
                        var iba = RawReferenceValueTypeObjectGetBytes(v);
                        ms.Write(iba);
                    }
                    else
                    {
                        if (v != null)
                            ms.Write(v);
                    }
                }
                var p = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.FlattenHierarchy);
                if (p.Length > 0)
                    foreach (var t in p)
                    {
                        var af = GetAllFields(t);
                        foreach (var infon in af)
                            if (infon.IsStatic)
                            {
                                var vi = infon.GetValue(null);
                                if (vi != null)
                                    ms.Write(vi);
                            }
                    }
                if (ms.BaseStream.Length == 0)
                    throw new Exception("Value and Reference Types, no meaningful data can be found.");
                return ms.BaseStream.ToArray();
            }
        return null;
    }
    private static IEnumerable<FieldInfo> GetAllFields(Type type)
    {
        return type.GetNestedTypes().SelectMany(GetAllFields)
            .Concat(type.GetFields());
    }
    /// <summary>
    ///     Serialize a serializable object
    ///     (GetBytesClass.cs)
    /// </summary>
    public static byte[] SerializeObject(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>(byte[] bytes)
    {
        using (var stream = new MemoryStream(bytes))
        {
            var result = (T) Formatter.Deserialize(stream);
            return result;
        }
    }
}

ObjectIndexer.cs

Sequential Ordering Object Indexer

Pass in an object get back it is sequential index 0…n. Session specific indexing.

Example Classes at the bottom.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
[DebuggerTypeProxy(typeof(HashSetDebugView<>))]
[DebuggerDisplay("Count = {" + nameof(Count) + "}")]
public class ObjectIndexer
{
    private const    int       BitWidth    = 64;
    private const    int       BucketDepth = 3;
    private readonly FNV1a64   hasher;
    internal         int       Count;
    private          long[]    Indices;
    internal         int       Length;
    public           List<int> loopcntlst = new List<int>();
    internal         object[]  Objects;
    private          int       Resizes;
    public ObjectIndexer(int size = 0)
    {
        if (size == 0)
            Length = 1607;
        else
            Length = size;
        Count   = 0;
        Indices = new long[Length * BucketDepth];
        Indices.Fill(-1);
        Objects = new object[Length * BucketDepth];
        Resizes = 0;
        hasher  = new FNV1a64();
    }
    public void Clear()
    {
        Count   = 0;
        Indices = new long[Length   * BucketDepth];
        Objects = new object[Length * BucketDepth];
    }
    private static bool IsPrimitive(object obj)
    {
        switch (Type.GetTypeCode(obj.GetType()))
        {
            case TypeCode.Boolean:
            case TypeCode.Char:
            case TypeCode.SByte:
            case TypeCode.Byte:
            case TypeCode.Int16:
            case TypeCode.UInt16:
            case TypeCode.Int32:
            case TypeCode.UInt32:
            case TypeCode.Single:
            case TypeCode.String:
            case TypeCode.Decimal:
            case TypeCode.DateTime:
            case TypeCode.Int64:
            case TypeCode.UInt64:
            case TypeCode.Double:
                return true;
            default:
                return false;
        }
    }
    private new bool Equals(object x, object y)
    {
        if (x == null || y == null)
            return false;
        var xp = IsPrimitive(x);
        var yp = IsPrimitive(y);
        if (xp != yp)
            return false;
        if (xp && yp)
            return x.Equals(y);
        var xb = x.GetBytes();
        var yb = y.GetBytes();
        if (xb.Length != yb.Length)
            return false;
        return xb.Compare(yb);
    }
    public long FindObject(object obj, out bool found)
    {
        var hashCode = hasher.ComputeHash(obj.GetBytes()).ToLong();
        var StepPos  = (hashCode & long.MaxValue) % Length;
        var loopCnt  = 0;
        while (true)
        {
            loopCnt++;
            if (loopCnt > BucketDepth * 8)
                throw new Exception("Bucket Depth too low.");
            var StartPos = (hashCode & long.MaxValue) % Length * BucketDepth;
            for (var i = StartPos; i < StartPos + BucketDepth; ++i)
            {
                if (Objects[i] == null)
                {
                    found = false;
                    loopcntlst.Add(loopCnt);
                    return i;
                }
                if (Equals(Objects[i], obj))
                {
                    found = true;
                    loopcntlst.Add(loopCnt);
                    return i;
                }
            }
            hashCode += StepPos;
        }
    }
    public bool Contains(object item)
    {
        FindObject(item, out var found);
        return found;
    }
    public long FindIndex(object obj)
    {
        long position;
        bool found;
        if (obj != null)
            position = FindObject(obj, out found);
        else
            throw new ArgumentException("Object cannot be null.");
        return found ? Indices[position] : -1;
    }
    public (long idx, bool found) GetIndex(object obj)
    {
        long position;
        bool found;
        if (obj != null)
            position = FindObject(obj, out found);
        else
            throw new ArgumentException("Object cannot be null.");
        long index;
        if (!found)
        {
            Objects[position] = obj;
            Indices[position] = Count++;
            index             = Indices[position];
            if (Count > Length)
                Resize();
        }
        else
        {
            index = Indices[position];
        }
        return (index, found);
    }
    public bool Add(object obj)
    {
        long position;
        bool found;
        if (obj != null)
            position = FindObject(obj, out found);
        else
            throw new ArgumentException("Object cannot be null.");
        if (!found)
            if (Objects[position] == null)
            {
                Objects[position] = obj;
                Indices[position] = Count++;
                if (Count > Length)
                    Resize();
            }
        return found;
    }
    public int AddRange(IEnumerable<object> items)
    {
        return items.Sum(i => !Add(i) ? 0 : 1);
    }
    private void Resize()
    {
        Resizes++;
        Length += Length * 2; 
        var idxArray = new long[Length * BucketDepth];
        idxArray.Fill(-1);
        var objArray = new object[Length * BucketDepth];
        var cidx     = Indices;
        var cobjs    = Objects;
        Indices = idxArray;
        Objects = objArray;
        for (var i = 0; i < cobjs.Length; ++i)
            if (cobjs[i] != null)
            {
                var position = FindObject(cobjs[i], out var D);
                Objects[position] = cobjs[i];
                Indices[position] = cidx[i];
            }
    }
    public void TrimExcess()
    {
        var hi = 0;
        for (var i = Length * BucketDepth - 1; i >= 0; --i)
            if (Indices[i] != -1)
                break;
            else
                hi = i;
        Array.Resize(ref Objects, hi);
        Array.Resize(ref Indices, hi);
        Length = hi;
        Recalculate();
    }
    private void Recalculate()
    {
        var idxArray = new long[Length * BucketDepth];
        idxArray.Fill(-1);
        var objArray = new object[Length * BucketDepth];
        var cidx     = Indices;
        var cobjs    = Objects;
        Indices = idxArray;
        Objects = objArray;
        for (var i = 0; i < cobjs.Length; ++i)
            if (cobjs[i] != null)
            {
                var position = FindObject(cobjs[i], out var D);
                Objects[position] = cobjs[i];
                Indices[position] = cidx[i];
            }
    }
    public object[] ToArray()
    {
        var array = new object[Count];
        var ptr   = 0;
        for (var i = 0; i < Objects.Length; ++i)
            if (Objects[i] != null)
                array[ptr++] = Objects[i];
        return array;
    }
    public void ExceptWith(IEnumerable<object> other)
    {
        if (other == null)
            throw new Exception("The other set must not be null.");
        if (Count == 0)
            return;
        if (Equals(other, this))
            Clear();
        else
            foreach (var obj in other)
                Remove(obj);
    }
    public void UnionWith(IEnumerable<object> other)
    {
        if (other == null)
            throw new Exception("The other set must not be null.");
        foreach (var obj in other)
            Add(obj);
    }
    public bool Overlaps(IEnumerable<object> other)
    {
        if (other == null)
            throw new Exception("The other set must not be null.");
        return Count != 0 && other.Any(Contains);
    }
    public bool ContainsAllElements(IEnumerable<object> other)
    {
        return other.All(Contains);
    }
    public int RemoveWhere(Predicate<object> pred)
    {
        if (pred == null)
            throw new Exception("The Predicate cannot be null.");
        var matches = 0;
        for (var i = 0; i < Objects.Length; ++i)
            if (Objects[i] != null)
            {
                var obj = Objects[i];
                if (pred(obj) && Remove(obj))
                    ++matches;
            }
        return matches;
    }
    public bool Remove(object oldItem)
    {
        var pos = FindObject(oldItem, out var D);
        if (!D)
            return false;
        Objects[pos] = null;
        Indices[pos] = -1;
        Count--;
        return true;
    }
}
Example HashSet Class Using Indexing.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
[DebuggerTypeProxy(typeof(HashSetDebugView<>))]
[DebuggerDisplay("Count = {" + nameof(Count) + "}")]
[Serializable]
public class TestHashSetObjectIndexerIdx<T> : IEnumerable<T>
{
    private T[]           _array;
    private ObjectIndexer Oi;
    public TestHashSetObjectIndexerIdx(int size = 0)
    {
        Oi     = new ObjectIndexer(size);
        _array = new T[size];
    }
    public int Count => Oi.Count;
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public T[] ToArray()
    {
        return (T[]) _array.Clone();
    }
    public void Clear()
    {
        Oi.Clear();
        Array.Clear(_array, 0, Oi.Length);
    }
    public bool Add(T item)
    {
        var idx = Oi.GetIndex(item);
        if (_array.Length != Oi.Length)
            Array.Resize(ref _array, Oi.Length);
        _array[idx.idx] = item;
        return idx.found;
    }
    public int AddRange(IEnumerable<T> items)
    {
        return items.Sum(i => !Add(i) ? 0 : 1);
    }
    public bool Contains(T item)
    {
        return Oi.ContainsObject(item);
    }
    public int FindEntry(T item)
    {
        return (int)Oi.FindIndex(item);
    }
    public IEnumerator<T> GetEnumerator()
    {
        return GetEnum();
    }
    public IEnumerator<T> GetEnum()
    {
        for (var i = 0; i < Count; i++)
            if (_array[i] != null)
                yield return _array[i];
    }
}
Example HashSet Class Using Object Indexer as a Base Class:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
[DebuggerTypeProxy(typeof(HashSetDebugView<>))]
[DebuggerDisplay("Count = {" + nameof(Count) + "}")]
[Serializable]
public class TestHashSetObjectIndexer<T> : IEnumerable<T>
{
    private  ObjectIndexer Oi;
    public TestHashSetObjectIndexer(int size = 0)
    {
        Oi = new ObjectIndexer(size);
    }
    public int Count => Oi.Count;
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public T[] ToArray()
    {
        var newArray = new T[Count];
        var copied   = 0;
        var a        = (object[]) Oi.Objects.Clone();
        for (var i = 0; i < Count && copied < Count; i++)
            if (a[i] != null)
                newArray[copied++] = (T)Convert.ChangeType(a[i], typeof(T));
        return newArray;
    }
    public void Clear()
    {
        Oi.Clear();
    }
    public bool Add(T item)
    {

        return Oi.Add(item);
    }
    public int AddRange(IEnumerable<T> items)
    {
        return items.Sum(i => !Add(i) ? 0 : 1);
    }
    public bool Contains(T item)
    {
        return Oi.ContainsObject(item);
    }
    public int FindEntry(T item)
    {
        var i = Oi.FindObject(item, out var d);
        return d ? (int) i : -1;
    }
    public IEnumerator<T> GetEnumerator()
    {
        return GetEnum();
    }
    public IEnumerator<T> GetEnum()
    {
        var a = (T[]) Oi.Objects.Clone();
        for (var i = 0; i < Count; i++)
            if (a[i] != null)
                yield return (T)Convert.ChangeType(a[i], typeof(T));
    }
}
Example Dictionary Class Using Object Indexer as a Base Class:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
[DebuggerTypeProxy(typeof(HashSetDebugView<>))]
[DebuggerDisplay("Count = {" + nameof(Count) + "}")]
[Serializable]
public class TestDictionaryObjectIndexer<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
{
    private ObjectIndexer _oi;
    private TValue[]      _values;
    public TestDictionaryObjectIndexer(int size = 0)
    {
        _oi     = new ObjectIndexer(size);
        _values = new TValue[size];
    }
    public int      Count  => _oi.Count;
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return GetEnum();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public TKey[] GetKeys()
    {
        var kp   = ToArray();
        var keys = new TKey[Count];
        for (var i = 0; i < Count; ++i)
            keys[i] = kp[i].Key;
        return keys;
    }
    public TValue[] GetValues()
    {
        var kp     = ToArray();
        var values = new TValue[Count];
        for (var i = 0; i < Count; ++i)
            values[i] = kp[i].Value;
        return values;
    }
    public void Clear()
    {
        _oi.Clear();
    }
    public bool Add(TKey key, TValue value)
    {
        var pi = _oi.GetIndex(key);
        if (!pi.found)
        {
            if (_values.Length != _oi.Length)
            {
                var nValues = new TValue[_oi.Length];
                Array.Copy(_values, nValues, _values.Length);
                _values = nValues;
            }
            _values[pi.idx] = value;
            return false;
        }
        _values[pi.idx] = value;
        return true;
    }
    public bool Contains(TKey item)
    {
        return _oi.ContainsObject(item);
    }
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnum()
    {
        var a = (object[]) _oi.Objects.Clone();
        for (var i = 0; i < Count; i++)
            if (a[i] != null)
            {
                var k = (TKey) Convert.ChangeType(a[i], typeof(TKey));
                var p = _oi.GetIndex(k);
                var v = _values[p.idx];
                yield return new KeyValuePair<TKey, TValue>((TKey) Convert.ChangeType(a[i], typeof(TKey)), v);
            }
    }
    public KeyValuePair<TKey, TValue>[] ToArray()
    {
        var a     = (object[]) _oi.Objects.Clone();
        var array = new KeyValuePair<TKey, TValue>[Count];
        var ptr   = 0;
        for (var i = 0; i < Count; i++)
            if (a[i] != null)
            {
                var k = (TKey) Convert.ChangeType(a[i], typeof(TKey));
                var p = _oi.GetIndex(k);
                var v = _values[p.idx];
                array[ptr++] = new KeyValuePair<TKey, TValue>((TKey) Convert.ChangeType(a[i], typeof(TKey)), v);
            }
        return array;
    }
}

Sha16512.cs

Variable 16Bit to 512Bit Hashing Algorithm

using System;
using System.Security.Cryptography;
[Serializable]
public class Sha16512 : HashAlgorithm
{
    private int           _bitWidth;
    private SHA512Managed _hash = new SHA512Managed();
    public Sha16512(int bitWidth)
    {
        if (bitWidth < 16 || bitWidth > 512)
            throw new ArgumentException($"Bit Width {bitWidth} must be between 16 and 512.");
        _bitWidth = bitWidth;
    }
    public override int HashSize => _bitWidth;
    public override void Initialize()
    {
    }
    protected override void HashCore(byte[] bytes, int ibStart, int cbSize)
    {
        var buf = bytes.SubByte(ibStart, cbSize);
        HashValue = _hash.ComputeHash(buf).SubByte(0, _bitWidth >> 3);
    }
    protected override byte[] HashFinal()
    {
        return (byte[]) HashValue.Clone();
    }
}

MonitorActionFuncWrapper.cs

Monitor Lock Wrapper

using System;
using System.Threading;
public class MonitorActionFuncWrapper : ConcurrencyCheck
{
    public void Lock(object localObject, Action action)
    {
        if (action == null)
            throw new Exception("Action argument cannot be null");
        if (CheckState())
        {
            var lockTaken = false;
            try
            {
                Monitor.Enter(localObject, ref lockTaken);
                action();
            }
            finally
            {
                if (lockTaken)
                    Monitor.Exit(localObject);
            }
        }
        else
        {
            action();
        }
    }
    public TResult Lock<TResult>(object localObject, Func<TResult> func)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
        {
            var lockTaken = false;
            try
            {
                Monitor.Enter(localObject, ref lockTaken);
                return func();
            }
            finally
            {
                if (lockTaken)
                    Monitor.Exit(localObject);
            }
        }
        return func();
    }
    public (TResult1, TResult2) Lock<TResult1, TResult2>(object localObject, Func<(TResult1, TResult2)> func)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
        {
            var lockTaken = false;
            try
            {
                Monitor.Enter(localObject, ref lockTaken);
                return func();
            }
            finally
            {
                if (lockTaken)
                    Monitor.Exit(localObject);
            }
        }
        return func();
    }
    public (TResult1, TResult2) Lock<TArg, TResult1, TResult2>(object localObject, Func<TArg, (TResult1, TResult2)> func, TArg arg)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
        {
            var lockTaken = false;
            try
            {
                Monitor.Enter(localObject, ref lockTaken);
                return func(arg);
            }
            finally
            {
                if (lockTaken)
                    Monitor.Exit(localObject);
            }
        }
        return func(arg);
    }
    public TResult Lock<TArg, TResult>(object localObject, Func<TArg, TResult> func, TArg arg)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
        {
            var lockTaken = false;
            try
            {
                Monitor.Enter(localObject, ref lockTaken);
                return func(arg);
            }
            finally
            {
                if (lockTaken)
                    Monitor.Exit(localObject);
            }
        }
        return func(arg);
    }
    public void Lock<TArg>(object localObject, Action<TArg> action, TArg arg)
    {
        if (action == null)
            throw new Exception("Action argument cannot be null");
        if (CheckState())
        {
            var lockTaken = false;
            try
            {
                Monitor.Enter(localObject, ref lockTaken);
                action(arg);
            }
            finally
            {
                if (lockTaken)
                    Monitor.Exit(localObject);
            }
        }
        else
        {
            action(arg);
        }
    }
}

ReaderWriterLockSlimActionFuncWrapper.cs

ReaderWriterLockSlim Wrapper See: MonitorActionFuncWrapper.cs

using System;
using System.Threading;
public class ReaderWriterLockSlimActionFuncWrapper : ConcurrencyCheck, IDisposable
{
    private bool                 _deadLock;
    private bool                 _disposed;
    private ReaderWriterLockSlim _rwl;
    public ReaderWriterLockSlimActionFuncWrapper(LockRecursionPolicy recursionPolicy = LockRecursionPolicy.NoRecursion)
    {
        _rwl = new ReaderWriterLockSlim(recursionPolicy);
        GC.SuppressFinalize(this);
    }
    public void Dispose()
    {
        Dispose(true);
    }
    public void Read(Action action)
    {
        if (action == null)
            throw new Exception("Action argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterReadLock();
                action();
            }
            finally
            {
                _rwl.ExitReadLock();
            }
        else
            action();
    }
    public TResult Read<TResult>(Func<TResult> func)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterReadLock();
                return func();
            }
            finally
            {
                _rwl.ExitReadLock();
            }
        return func();
    }
    public (TResult1, TResult2) Read<TResult1, TResult2>(Func<(TResult1, TResult2)> func)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterReadLock();
                return func();
            }
            finally
            {
                _rwl.ExitReadLock();
            }
        return func();
    }
    public (TResult1, TResult2) Read<TArg, TResult1, TResult2>(Func<TArg, (TResult1, TResult2)> func, TArg arg)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterReadLock();
                return func(arg);
            }
            finally
            {
                _rwl.ExitReadLock();
            }
        return func(arg);
    }
    public TResult Read<TArg, TResult>(Func<TArg, TResult> func, TArg arg)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterReadLock();
                return func(arg);
            }
            finally
            {
                _rwl.ExitReadLock();
            }
        return func(arg);
    }
    public void Read<TArg>(Action<TArg> action, TArg arg)
    {
        if (action == null)
            throw new Exception("Action argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterReadLock();
                action(arg);
            }
            finally
            {
                _rwl.ExitReadLock();
            }
        else
            action(arg);
    }
    public void Write(Action action)
    {
        if (action == null)
            throw new Exception("Action argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterWriteLock();
                action();
            }
            finally
            {
                _rwl.ExitWriteLock();
            }
        else
            action();
    }
    public TResult Write<TResult>(Func<TResult> func)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterWriteLock();
                return func();
            }
            finally
            {
                _rwl.ExitWriteLock();
            }
        return func();
    }
    public (TResult1, TResult2) Write<TResult1, TResult2>(Func<(TResult1, TResult2)> func)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterWriteLock();
                return func();
            }
            finally
            {
                _rwl.ExitWriteLock();
            }
        return func();
    }
    public (TResult1, TResult2) Write<TArg, TResult1, TResult2>(Func<TArg, (TResult1, TResult2)> func, TArg arg)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterWriteLock();
                return func(arg);
            }
            finally
            {
                _rwl.ExitWriteLock();
            }
        return func(arg);
    }
    public TResult Write<TArg, TResult>(Func<TArg, TResult> func, TArg arg)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterWriteLock();
                return func(arg);
            }
            finally
            {
                _rwl.ExitWriteLock();
            }
        return func(arg);
    }
    public void Write<TArg>(Action<TArg> action, TArg arg)
    {
        if (action == null)
            throw new Exception("Action argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterWriteLock();
                action(arg);
            }
            finally
            {
                _rwl.ExitWriteLock();
            }
        else
            action(arg);
    }
    public void ReadUpdate(Action action)
    {
        if (action == null)
            throw new Exception("Action argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterUpgradeableReadLock();
                try
                {
                    _rwl.EnterWriteLock();
                    action();
                }
                finally
                {
                    _rwl.ExitWriteLock();
                }
            }
            finally
            {
                _rwl.ExitUpgradeableReadLock();
            }
        else
            action();
    }
    public TResult ReadUpdate<TResult>(Func<TResult> func)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterUpgradeableReadLock();
                try
                {
                    _rwl.EnterWriteLock();
                    return func();
                }
                finally
                {
                    _rwl.ExitWriteLock();
                }
            }
            finally
            {
                _rwl.ExitUpgradeableReadLock();
            }
        return func();
    }
    public (TResult1, TResult2) ReadUpdate<TResult1, TResult2>(Func<(TResult1, TResult2)> func)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterUpgradeableReadLock();
                try
                {
                    _rwl.EnterWriteLock();
                    return func();
                }
                finally
                {
                    _rwl.ExitWriteLock();
                }
            }
            finally
            {
                _rwl.ExitUpgradeableReadLock();
            }
        return func();
    }
    public (TResult1, TResult2) ReadUpdate<TArg, TResult1, TResult2>(Func<TArg, (TResult1, TResult2)> func, TArg arg)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterUpgradeableReadLock();
                try
                {
                    _rwl.EnterWriteLock();
                    return func(arg);
                }
                finally
                {
                    _rwl.ExitWriteLock();
                }
            }
            finally
            {
                _rwl.ExitUpgradeableReadLock();
            }
        return func(arg);
    }
    public TResult ReadUpdate<TArg, TResult>(Func<TArg, TResult> func, TArg arg)
    {
        if (func == null)
            throw new Exception("Func argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterUpgradeableReadLock();
                try
                {
                    _rwl.EnterWriteLock();
                    return func(arg);
                }
                finally
                {
                    _rwl.ExitWriteLock();
                }
            }
            finally
            {
                _rwl.ExitUpgradeableReadLock();
            }
        return func(arg);
    }
    public void ReadUpdate<TArg>(Action<TArg> action, TArg arg)
    {
        if (action == null)
            throw new Exception("Action argument cannot be null");
        if (CheckState())
            try
            {
                _rwl.EnterUpgradeableReadLock();
                try
                {
                    _rwl.EnterWriteLock();
                    action(arg);
                }
                finally
                {
                    _rwl.ExitWriteLock();
                }
            }
            finally
            {
                _rwl.ExitUpgradeableReadLock();
            }
        else
            action(arg);
    }
    ~ReaderWriterLockSlimActionFuncWrapper()
    {
        if (_rwl != null)
            _rwl.Dispose();
    }
    protected virtual void Dispose(bool disposing)
    {
        if (_disposed)
            throw new Exception("Already Disposed");
        try
        {
            _rwl.Dispose();
            _disposed = true;
            _rwl      = null;
        }
        catch (SynchronizationLockException) when (disposing)
        {
            _deadLock = true;
        }
        finally
        {
            if (!_disposed && disposing)
                GC.ReRegisterForFinalize(this);
        }
    }
}