RandomBigInt.cs

BigInteger Random Number Generator

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

ObjectAssociativeArray.cs

Key based, Fast Searchable Values, Multiple Value Arrays.

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

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

ObjectDictionary.cs

Object Dictionary Single Associative Array, Searchable Keys and Values

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

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

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

SizeHelper32.cs

Gradually Resize

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

ObjectBase.cs

Base Object Array Class

Updated: May-04,2021

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.Serialization;
using System.Security.Cryptography;
using System.Threading;
/// <summary>
///     Name: ObjectBase.cs
///     Date: January-1, 2021
///     Note: Map indexed object array.
/// </summary>
[DebuggerDisplay("Count = {" + nameof(Count) + "}")]
[Serializable]
public class ObjectBase : MonitorActionFuncWrapper, IEnumerable<object>
{
    [NonSerialized] private readonly SizeHelper32      _sh = new();
    [NonSerialized] private readonly SerializationInfo _sInfo;
    private volatile                 object[]          _array;
    [NonSerialized] private          HashAlgorithm     _hash;
    [NonSerialized] private volatile Set20B            _map;
    public volatile                  int               Count;
    public ObjectBase() : this(1024)
    {
    }
    public ObjectBase(int size, int bitWidth = 64)
    {
        BitWidth = bitWidth;
        SelectHashAlgorithm(bitWidth);
        _array = new object[size];
        _map   = new Set20B(size);
    }
    protected ObjectBase(SerializationInfo info, StreamingContext context)
    {
        _sInfo = info;
    }
    public object this[int index]
    {
        get
        {
            return Lock(this, () =>
            {
                var array = _array;
                if (index >= Count)
                    throw new Exception("Error: Index out of range.");
                return array[index];
            });
        }
    }
    public int BitWidth
    {
        get;
        private set;
    }
    public IEnumerator<object> GetEnumerator()
    {
        return Lock(this, () =>
        {
            return GetEnum();
        });
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return Lock(this, () =>
        {
            return GetEnum();
        });
    }
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("BitWidth", BitWidth);
        info.AddValue("Array",    _array, typeof(object[]));
    }
    public void OnDeserialization(object sender)
    {
        if (_sInfo == null)
            return;
        BitWidth = _sInfo.GetInt32("BitWidth");
        Count    = 0;
        var array = (object[]) _sInfo.GetValue("Array", typeof(object[]));
        if (array == null)
            throw new Exception("Array cannot be null.");
        foreach (var t in array)
            Add(t);
    }
    public bool Add(object item)
    {
        return Lock(this, () =>
        {
            var (idx, exists) = GetIndex(item);
            if (idx >= _array.Length)
                Array.Resize(ref _array, (int) _sh.GetNewSize((ulong) _array.Length));
            if (exists == false)
            {
                _array[idx] = item;
                Interlocked.Increment(ref Count);
            }
            return exists == false;
        });
    }
    public void Clear()
    {
        Lock(this, () =>
        {
            _array = new object[_array.Length];
            _map   = new Set20B(_array.Length);
        });
    }
    private IEnumerator<object> GetEnum()
    {
        var ary = _array;
        var cnt = Count;
        for (var i = 0; i < cnt; i++)
            yield return ary[i];
    }
    public object[] ToArray()
    {
        return Lock(this, () =>
        {
            var newArray = new object[Count];
            using (var en = GetEnumerator())
            {
                var ptr = 0;
                while (en.MoveNext())
                {
                    var value = en.Current;
                    if (value == null)
                        break;
                    newArray[ptr++] = value;
                }
                return newArray;
            }
        });
    }
    public bool Contains(object item)
    {
        return Lock(this, () =>
        {
            return MapContains(item);
        });
    }
    private bool MapContains(object obj)
    {
        if (obj == null)
            throw new ArgumentNullException(nameof(obj));
        var bytes = obj.GetBytes();
        var hash  = _hash.ComputeHash(bytes, 0, bytes.Length);
        return _map.Contains(hash);
    }
    internal (int idx, bool exists) GetIndex(object obj, bool add = true)
    {
        return Lock(this, () =>
        {
            var bytes = obj.GetBytes();
            var hash  = new byte[0];
            hash = _hash.ComputeHash(bytes, 0, bytes.Length);
            var exists = false;
            if (!_map.Contains(hash))
            {
                if (add)
                    _map.Add(hash);
            }
            else
            {
                exists = true;
            }
            return (_map.FindEntry(hash), exists);
        });
    }
    private void SelectHashAlgorithm(int bitWidth)
    {
        BitWidth = bitWidth;
        switch (bitWidth)
        {
            case 64:
                _hash = new FNV1a64();
                break;
            case 128:
                _hash = new Murmur3();
                break;
            case 256:
                _hash = new SHA256Managed();
                break;
            case 512:
                _hash = new SHA512Managed();
                break;
            case 768:
                _hash = new SHA3Managed(768);
                break;
            default:
                throw new ArgumentException("Supported bit widths are: 64, 128, 256, 512 and 768 Bits.");
        }
    }
    internal class Set20B
    {
        private readonly IEqualityComparer<byte[]> _comparer;
        private          int                       _count;
        private          int[]                     _hashBuckets;
        private          Slot[]                    _slots;
        public Set20B(int size)
        {
            _comparer    = new ArrayComparer();
            _hashBuckets = new int[size];
            _slots       = new Slot[size];
            _count       = 0;
        }
        private IEnumerator<byte[]> GetEnumerator()
        {
            for (var i = 0; i < _count; i++)
                if (_slots[i].HashCode > 0)
                    yield return _slots[i].Value;
        }
        public bool Add(byte[] item)
        {
            var hashCode = _comparer.GetHashCode(item) & int.MaxValue;
            if (FindEntry(item, hashCode) != -1)
                return true;
            if (_count >= _slots.Length)
                Resize();
            var hashPos = hashCode % _hashBuckets.Length;
            _slots[_count].Next     = _hashBuckets[hashPos] - 1;
            _slots[_count].Value    = item;
            _slots[_count].HashCode = hashCode;
            _hashBuckets[hashPos]   = _count + 1;
            ++_count;
            return false;
        }
        private void Resize()
        {
            var newSize        = (_hashBuckets.Length + _hashBuckets.Length / 4 * 3) | 1;
            var newSlots       = new Slot[newSize];
            var newHashBuckets = new int[newSize];
            var newCount       = 0;
            var en             = GetEnumerator();
            while (en.MoveNext())
            {
                var item     = en.Current;
                var hashCode = _comparer.GetHashCode(item) & int.MaxValue;
                var hashPos  = hashCode % newHashBuckets.Length;
                newSlots[newCount].Next     = newHashBuckets[hashPos] - 1;
                newSlots[newCount].Value    = item;
                newSlots[newCount].HashCode = hashCode;
                newHashBuckets[hashPos]     = newCount + 1;
                ++newCount;
            }
            _slots       = newSlots;
            _hashBuckets = newHashBuckets;
            _count       = newCount;
        }
        private int FindEntry(byte[] item, int hashCode)
        {
            for (var position = _hashBuckets[hashCode % _hashBuckets.Length] - 1; position >= 0; position = _slots[position].Next)
                if (_slots[position].HashCode == hashCode && _comparer.Equals(_slots[position].Value, item))
                    return position;
            return -1;
        }
        public int FindEntry(byte[] item)
        {
            var hashCode = _comparer.GetHashCode(item) & int.MaxValue;
            for (var position = _hashBuckets[hashCode % _hashBuckets.Length] - 1; position >= 0; position = _slots[position].Next)
                if (_slots[position].HashCode == hashCode && _comparer.Equals(_slots[position].Value, item))
                    return position;
            return -1;
        }
        public bool Contains(byte[] item)
        {
            return FindEntry(item, _comparer.GetHashCode(item) & int.MaxValue) != -1;
        }
        private struct Slot
        {
            public int    HashCode;
            public int    Next;
            public byte[] Value;
        }
    }
}

MSet15.cs

Hashing Set Class

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

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

AcDictionary.cs

Support Dictionary for Hash Mapping

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

SessionId.cs

Session Id Class Hash Reduction Mapping

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

EntropyEx.cs

Generic Entropy Class

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

MemoryStreamReader.cs

MemoryStream Reader Class

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

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

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

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


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