CustomArray.cs

Custom Array Class

using System;
using System.Collections;
using System.Collections.Generic;
public class CustomArray<T> : IEnumerable<T>
{
    private          T[]               _array;
    private volatile MonitorActionFunc _maf;
    public volatile  int               Count;
    public CustomArray(int cap)
    {
        _array = new T[cap];
        _maf   = new MonitorActionFunc();
        Count  = 0;
    }
    public int Length
    {
        get
        {
            var tmpThis = this;
            return tmpThis._maf.Lock(tmpThis, () => _array.Length);
        }
    }
    public T this[int index]
    {
        get
        {
            var array   = _array;
            var idx     = index;
            var tmpThis = this;
            return tmpThis._maf.Lock(tmpThis, () =>
            {
                if (idx > array.Length)
                    throw new Exception($"Error: Index {idx} out of range {array.Length}");
                return array[idx];
            });
        }
        set
        {
            var tmpThis = this;
            var idx     = index;
            tmpThis._maf.Lock(tmpThis, () =>
            {
                if (idx >= _array.Length)
                    Array.Resize(ref _array, idx + idx / 4 * 3);
                _array[idx] = value;
                Count++;
            });
        }
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public void Clear()
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            Array.Clear(_array, 0, _array.Length);
            Count = 0;
        });
    }
    public IEnumerator<T> GetEnumerator()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            return GetEnum();
        });
    }
    private IEnumerator<T> GetEnum()
    {
        var array = _array;
        var count = Count;
        for (var i = 0; i < count; i++)
            yield return array[i];
    }
    public T[] ToArray()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            var newtArray = new T[Count];
            Array.Copy(_array, 0, newtArray, 0, Count);
            return newtArray;
        });
    }
}

TDArray.cs

Simple Concurrent Array Class

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
[Serializable]
public class TDArray<T> : IEnumerable<T>
{
    private          T[]               _array;
    private volatile MonitorActionFunc _maf;
    public volatile  int               Count;
    public TDArray(int cap)
    {
        _array = new T[cap];
        _maf   = new MonitorActionFunc();
        Count  = 0;
    }
    public int Length
    {
        get
        {
            var tmpThis = this;
            return tmpThis._maf.Lock(tmpThis, () => _array.Length);
        }
    }
    public T this[int index]
    {
        get
        {
            var array   = _array;
            var idx = index;
            var tmpThis = this;
            return tmpThis._maf.Lock(tmpThis, () =>
            {
                if (idx > array.Length)
                    throw new Exception("Error: Index out of range.");
                return array[idx];
            });
        }
        set
        {
            var tmpThis = this;
            var idx     = index;
            tmpThis._maf.Lock(tmpThis, () =>
            {
                if (idx >= _array.Length)
                    Array.Resize(ref _array, idx * 2);
                _array[idx] = value;
            });
        }
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public void Add(T item)
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            if (Count >= _array.Length)
                Array.Resize(ref _array, _array.Length + _array.Length / 4 * 3);
            _array[Count] = item;
            Interlocked.Increment(ref Count);
        });
    }
    public void Clear()
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            Array.Clear(_array, 0, _array.Length);
            Count = 0;
        });
    }
    public IEnumerator<T> GetEnumerator()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            return GetEnum();
        });
    }
    private IEnumerator<T> GetEnum()
    {
        var array = _array;
        var count = Count;
        for (var i = 0; i < count; i++)
            yield return array[i];
    }
}

DynamicArray.cs

Use Concurrently or Non-Concurrently

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

[Serializable]
public class DynamicArray<T> : IEnumerable<T>
{
    private volatile T[]               _array;
    private volatile MonitorActionFunc _maf;
    public volatile  int               Count;
    public DynamicArray(int cap)
    {
        Count  = 0;
        _array = new T[cap];
        _maf   = new MonitorActionFunc();
    }
    public DynamicArray(IEnumerable<T> collection)
    {
        var enumerable = collection as T[] ?? collection.ToArray();
        Count  = enumerable.Length;
        _array = new T[Count];
        Array.Copy(enumerable, 0, _array, 0, Count);
        _maf = new MonitorActionFunc();
    }
    public int Length
    {
        get
        {
            var tmpThis = this;
            return tmpThis._maf.Lock(tmpThis, () => _array.Length);
        }
    }
    public T this[int index]
    {
        get
        {
            var array   = _array;
            var tmpThis = this;
            return tmpThis._maf.Lock(tmpThis, () =>
            {
                if (index > array.Length)
                    throw new Exception("Error: Index out of range.");
                return array[index];
            });
        }
        set
        {
            var tmpThis = this;
            tmpThis._maf.Lock(tmpThis, () =>
            {
                if (index > _array.Length)
                    throw new Exception("Error: Index out of range.");
                _array[index] = value;
            });
        }
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return GetEnumerator();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
    public void Resize(int newSize)
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            Array.Resize(ref _array, newSize);
        });
    }
    public void Add(T item)
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            if (Count >= _array.Length)
                throw new Exception("Item exceeds array length.");
            _array[Count] = item;
            Interlocked.Increment(ref Count);
        });
    }
    public void AddRange(IEnumerable<T> collection)
    {
        var enumerable = collection as T[] ?? collection.ToArray();
        Count  = enumerable.Length;
        _array = new T[Count];
        Array.Copy(enumerable, 0, _array, 0, Count);
    }
    public T[] ToArray()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            var newtArray = new T[Count];
            Array.Copy(_array, 0, newtArray, 0, Count);
            return newtArray;
        });
    }
    public void Clean()
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            var newtArray = new T[Count];
            Array.Copy(_array, 0, newtArray, 0, Count);
            _array = newtArray;
        });
    }
    public void Clear()
    {
        var tmpThis = this;
        tmpThis._maf.Lock(tmpThis, () =>
        {
            Array.Clear(_array, 0, Count);
            Count = 0;
        });
    }
    public long IndexOf(T item)
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () => Array.IndexOf(_array, item, 0));
    }
    public IEnumerator<T> GetEnumerator()
    {
        var tmpThis = this;
        return tmpThis._maf.Lock(tmpThis, () =>
        {
            return GetEnum();
        });
    }
    private IEnumerator<T> GetEnum()
    {
        var array = _array;
        var count = Count;
        for (var i = 0; i < count; i++)
            yield return array[i];
    }
}

DynArrayStruct32.cs

Dynamic Concurrent Generic Array Structure 32 Bit

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using Microsoft.VisualBasic.Devices;
[DebuggerDisplay("Count = {Count}")]
[Serializable]
public struct DynArrayStruct32<T> : IEnumerable<T>
{
    public const     int               ShiftCount  = 20;
    public const     int               Granularity = 1 << ShiftCount;
    private volatile Table             _table;
    public volatile  T[][]             Arrays;
    public volatile  int               MaximumNumberOfArrays;
    private volatile MonitorActionFunc maf;
    public DynArrayStruct32(long size)
    {
        if (size < Granularity)
            size = Granularity;
        try
        {
            maf                         = new MonitorActionFunc();
            _table                      = new Table();
            MaximumNumberOfArrays       = (int) (new ComputerInfo().AvailablePhysicalMemory / Granularity);
            _table.NumberOfActiveArrays = (int) ((size + (Granularity - 1))                 / Granularity);
            var val = (long) _table.NumberOfActiveArrays                                    * Granularity;
            _table.Length = Interlocked.Read(ref val);
            Arrays        = new T[MaximumNumberOfArrays][];
            for (var i = 0; i < _table.NumberOfActiveArrays; ++i)
                Arrays[i] = new T[Granularity];
        }
        catch (Exception ex)
        {
            throw new Exception($"'Initialize:DynArray' Exception: {ex.Message}");
        }
    }
    public DynArrayStruct32(IEnumerable<T> collection)
    {
        try
        {
            maf                   = new MonitorActionFunc();
            _table                = new Table();
            MaximumNumberOfArrays = (int) (new ComputerInfo().AvailablePhysicalMemory / Granularity);
            var size = Granularity;
            _table.NumberOfActiveArrays = (size + (Granularity - 1)) / Granularity;
            var val = (long) _table.NumberOfActiveArrays * Granularity;
            _table.Length = Interlocked.Read(ref val);
            Arrays        = new T[MaximumNumberOfArrays][];
            for (var i = 0; i < _table.NumberOfActiveArrays; ++i)
                Arrays[i] = new T[Granularity];
        }
        catch (Exception ex)
        {
            throw new Exception($"'Initialize:DynArray' Exception: {ex.Message}");
        }
        foreach (var item in collection)
            Add(item);
    }
    public long Count
    {
        get
        {
            var tmpThis = this;
            return tmpThis.maf.Lock(tmpThis, () =>
            {
                return tmpThis._table.Count;
            });
        }
    }
    public long Length
    {
        get
        {
            var tmpThis = this;
            return tmpThis.maf.Lock(tmpThis, () =>
            {
                return tmpThis._table.Length;
            });
        }
    }
    public T this[long index]
    {
        get
        {
            var tmpThis = this;
            return tmpThis.maf.Lock(tmpThis, () =>
            {
                if (index >= tmpThis._table.Length)
                    throw new Exception($"Getter: Index out of bounds, Index: '{index}' must be less than the Length: '{tmpThis.Length}'.");
                return tmpThis.Arrays[index >> ShiftCount][index & (Granularity - 1)];
            });
        }
        set
        {
            var tmpThis = this;
            tmpThis.maf.Lock(tmpThis, () =>
            {
                if (index + 1 > tmpThis._table.Length)
                    tmpThis.EnsureSize();
                tmpThis.Arrays[index >> ShiftCount][index & (Granularity - 1)] = value;
                tmpThis._table.Count++;
            });
        }
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return new Enumerator(this);
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return new Enumerator(this);
    }
    public void Add(T Item)
    {
        var tmpThis = this;
        tmpThis.maf.Lock(tmpThis, () =>
        {
            if (tmpThis._table.Count + 1 > tmpThis._table.Length)
                tmpThis.EnsureSize();
            tmpThis.Arrays[tmpThis._table.Count >> ShiftCount][tmpThis._table.Count & (Granularity - 1)] = Item;
            tmpThis._table.Count++;
        });
    }
    public void AddRange(IEnumerable<T> collection)
    {
        var tmpThis = this;
        tmpThis.maf.Lock(tmpThis, () =>
        {
            foreach (var item in collection)
                tmpThis.Add(item);
        });
    }
    public Enumerator GetEnumerator()
    {
        return new Enumerator(this);
    }
    private void EnsureSize()
    {
        try
        {
            _table.NumberOfActiveArrays++;
            if (_table.NumberOfActiveArrays >= MaximumNumberOfArrays)
                throw new Exception($"Number of active arrays {_table.NumberOfActiveArrays} cannot meet or exceed the maximum number of arrays {MaximumNumberOfArrays} allowed.");
            var val = (long) _table.NumberOfActiveArrays * Granularity;
            _table.Length                           = Interlocked.Read(ref val);
            Arrays[_table.NumberOfActiveArrays - 1] = new T[Granularity];
        }
        catch (Exception ex)
        {
            throw new Exception($"'EnsureSize:DynArray' Exception: {ex.Message}");
        }
    }
    public void Clear()
    {
        var tmpThis = this;
        tmpThis.maf.Lock(tmpThis, () =>
        {
            for (var a = 0L; a < tmpThis._table.NumberOfActiveArrays; a++)
                Array.Clear(tmpThis.Arrays[a], 0, Granularity);
            tmpThis._table.Count = 0;
        });
    }
    public long IndexOf(T item)
    {
        var tmpThis = this;
        return tmpThis.maf.Lock(tmpThis, () =>
        {
            var i = 0L;
            for (; i < tmpThis._table.NumberOfActiveArrays; i++)
            {
                var pos = Array.IndexOf(tmpThis.Arrays[i], item, 0);
                if (pos != -1)
                    return i * Granularity + pos;
            }
            return -1;
        });
    }
    public DynArrayStruct32<T> Copy(int newsize)
    {
        var tmpThis = this;
        return tmpThis.maf.Lock(tmpThis, () =>
        {
            var temp = new DynArrayStruct32<T>(newsize);
            for (var a = 0L; a < tmpThis._table.NumberOfActiveArrays; a++)
                Array.Copy(tmpThis.Arrays[a], temp.Arrays[a], Granularity);
            return temp;
        });
    }
    public DynArrayStruct32<T> CopyOrInsert(T item, int newsize)
    {
        var tmpThis = this;
        return tmpThis.maf.Lock(tmpThis, () =>
        {
            if (newsize > tmpThis._table.Length)
            {
                var temp = new DynArrayStruct32<T>(newsize);
                for (var a = 0L; a < tmpThis._table.NumberOfActiveArrays; a++)
                    Array.Copy(tmpThis.Arrays[a], temp.Arrays[a], Granularity);
                temp._table.Count = tmpThis.Count;
                temp.Add(item);
                return temp;
            }
            tmpThis.Add(item);
            return tmpThis;
        });
    }
    public void FromArray(T[][] array)
    {
        var tmpThis = this;
        tmpThis.maf.Lock(tmpThis, () =>
        {
            tmpThis._table.NumberOfActiveArrays = array.GetUpperBound(0) + 1;
            var val = (long) tmpThis._table.NumberOfActiveArrays * Granularity;
            tmpThis._table.Length = Interlocked.Read(ref val);
            tmpThis.Arrays        = new T[tmpThis._table.NumberOfActiveArrays][];
            for (var i = 0; i < tmpThis._table.NumberOfActiveArrays; ++i)
                tmpThis.Arrays[i] = new T[Granularity];
            for (var a = 0L; a < tmpThis._table.NumberOfActiveArrays; a++)
                Array.Copy(array[a], tmpThis.Arrays[a], Granularity);
        });
    }
    public T[][] ToArray()
    {
        var tmpThis = this;
        return tmpThis.maf.Lock(tmpThis, () =>
        {
            var ta = new T[tmpThis._table.NumberOfActiveArrays][];
            for (var i = 0; i < tmpThis._table.NumberOfActiveArrays; ++i)
                ta[i] = new T[Granularity];
            for (var a = 0L; a < tmpThis._table.NumberOfActiveArrays; a++)
                Array.Copy(tmpThis.Arrays[a], ta[a], Granularity);
            return ta;
        });
    }
    public T[] ToArray32()
    {
        var tmpThis = this;
        return tmpThis.maf.Lock(tmpThis, () =>
        {
            if (tmpThis.Count >= uint.MaxValue)
                throw new Exception("Too many elements to cast to a 32Bit array.");
            var array = new T[tmpThis.Count];
            var cnt   = 0l;
            for (var a = 0L; a < tmpThis._table.NumberOfActiveArrays && cnt < uint.MaxValue; a++, cnt += Granularity)
                Array.Copy(tmpThis.Arrays[a], 0, array, a * Granularity, Granularity);
            return array;
        });
    }
    public (int l, int r) BoundsFromIndex(int index)
    {
        var l = index >> ShiftCount;
        var r = index & (Granularity - 1);
        return (r, r);
    }
    public int IndexFromBounds(int l, int r)
    {
        return l * Granularity + r;
    }
    private class Table
    {
        public          long Count;
        public          long Length;
        public volatile int  NumberOfActiveArrays;
    }
    [Serializable]
    public class Enumerator : IEnumerator<T>
    {
        private readonly DynArrayStruct32<T> _array;
        private volatile eTable              _eTable = new eTable();
        internal Enumerator(DynArrayStruct32<T> array)
        {
            _array         = array;
            _eTable._index = 0;
            Current        = default;
        }
        public T Current
        {
            get;
            private set;
        }
        object IEnumerator.Current
        {
            get
            {
                return _array.maf.Lock(this, () =>
                {
                    if (_eTable._index == _array._table.Count + 1)
                        throw new Exception($"Enumerator out of range: {_eTable._index}");
                    return Current;
                });
            }
        }
        public void Dispose()
        {
        }
        public bool MoveNext()
        {
            return _array.maf.Lock(this, () =>
            {
                for (; _eTable._index < _array._table.Count; ++_eTable._index)
                    if (_eTable._index < _array._table.Count || _eTable._index == 0)
                    {
                        Current = _array[_eTable._index];
                        ++_eTable._index;
                        return true;
                    }
                _eTable._index = _array._table.Count + 1;
                Current        = default;
                return false;
            });
        }
        void IEnumerator.Reset()
        {
            _eTable._index = 0;
            Current        = default;
        }
        private class eTable
        {
            public long _index;
        }
    }
}

MiniArray.cs

A Small Generic Array Class

using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
[Serializable]
public class MiniArray<T> : IEnumerable<T>
{
    public T[] Array;
    public MiniArray() : this(101)
    {
    }
    public MiniArray(int cap)
    {
        Count = 0;
        Array = new T[cap];
    }
    public int Count
    {
        get;
        private set;
    }
    public T this[int index]
    {
        get
        {
            if (index > Array.Length)
                throw new Exception("Error: Index out of range.");
            return Array[index];
        }
        set
        {
            EnsureSize();
            Array[index] = value;
            Count++;
        }
    }
    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        return new Enumerator<T>(this);
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return new Enumerator<T>(this);
    }
    private void EnsureSize()
    {
        if (Count >= Array.Length)
        {
            var NewLength = Array.Length == 0 ? 1 : Array.Length * 2;
            var newtArray = new T[NewLength];
            System.Array.Copy(Array, 0, newtArray, 0, Array.Length);
            Array = newtArray;
        }
    }
    public void Add(T item)
    {
        EnsureSize();
        Array[Count] = item;
        Count++;
    }
    public T[] ToArray()
    {
        var newtArray = new T[Count];
        System.Array.Copy(Array, 0, newtArray, 0, Count);
        return newtArray;
    }
    public IEnumerable<T> All()
    {
        for (var i = 0; i < Count; ++i)
            yield return Array[i];
    }
    public void Clean()
    {
        var newtArray = new T[Count];
        System.Array.Copy(Array, 0, newtArray, 0, Count);
        Array = newtArray;
    }
    public void Clear()
    {
        System.Array.Clear(Array, 0, Count);
        Count = 0;
    }
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct Enumerator<T> : IEnumerator<T>
{
    private readonly MiniArray<T> thing;
    private          int          index;
    internal Enumerator(MiniArray<T> thing)
    {
        this.thing = thing;
        index      = 0;
        Current    = default;
    }
    public void Dispose()
    {
    }
    public bool MoveNext()
    {
        var tthing = thing;
        if (index < tthing.Count)
        {
            Current = tthing[index];
            index++;
            return true;
        }
        index   = thing.Count + 1;
        Current = default;
        return false;
    }
    public T Current
    {
        get;
        private set;
    }
    object IEnumerator.Current => Current;
    void IEnumerator.Reset()
    {
        index   = 0;
        Current = default;
    }
}

SizeHelper.cs

Non-Linear Array Size Adjustment Class

using System;
using System.Collections.Generic;
using Microsoft.VisualBasic.Devices;
public class SizeHelper<T>
{
    private static readonly FixedIntXPrimality bp = new FixedIntXPrimality(64);
    private readonly        int                AllocatedSizeLimit;
    public                  int[]              Curve;
    private                 int                Resizes;
    public SizeHelper()
    {
        var measure   = new MeasureSize<T>();
        var sizeOfOne = measure.GetByteSize();
        var am        = new ComputerInfo().AvailablePhysicalMemory;
        AllocatedSizeLimit = (int) ((long) am / sizeOfOne);
    }
    public int GetNewSize(int currentSize)
    {
        Resizes++;
        if (Curve == null)
            BuildCurve(currentSize);
        foreach (var v in Curve)
            if (v > currentSize)
                return v;
        var nv = GetNextValue(currentSize);
        return nv != -1 ? nv : int.MaxValue;
    }
    private int GetNextValue(int currentValue)
    {
        for (var value = currentValue | 1; value < AllocatedSizeLimit; value += 16384)
        {
            if (value < 0)
                break;
            if (bp.IsPrime(value))
                return value + 1;
        }
        return -1;
    }
    private void BuildCurve(int Size)
    {
        int Sizer(int oldSize)
        {
            try
            {
                oldSize = (int) (uint) oldSize;
                var log     = Math.Log(oldSize);
                var inv     = 1.0 / log * 4;
                var newSize = oldSize   * (1.0 + inv);
                return (int) (uint) newSize;
            }
            catch
            {
                return AllocatedSizeLimit;
            }
        }
        var curlst = new List<int>();
        var value  = Size | 1;
        do
        {
            value = Sizer(value);
            if (value < 0)
                break;
            if (value < AllocatedSizeLimit)
                curlst.Add(value);
        } while (value < AllocatedSizeLimit);
        Curve = curlst.ToArray();
        var dl   = new List<int>();
        var last = 0;
        for (var i = 0; i < Curve.Length; ++i)
        {
            if (i > 0)
                last = Curve[i - 1];
            var v = Curve[i];
            dl.Add(v - last);
        }
        var str = "";
        foreach (var v in dl)
            str += $"{v},";
    }
}

ArrayMixer.cs

Uses Sha3 to Shuffle Primitive Arrays

using System;
public class ArrayMixer
{
    private readonly SHA3ModInt _alg;
    private readonly int        _moveSize;
    public ArrayMixer() : this(256, 24)
    {
    }
    public ArrayMixer(int hashSize) : this(hashSize, 24)
    {
    }
    public ArrayMixer(int hashSize, int rounds)
    {
        _alg      = new SHA3ModInt(hashSize, rounds);
        _moveSize = _alg.ComputeHash(2.GetBytes()).Length;
    }
    public byte[] Mix(byte[] buf, int iterations = 1000)
    {
        var bufferSize = buf.Length;
        var lBuffer    = new byte[_moveSize];
        var oBuffer    = new byte[bufferSize];
        for (var i = 0; i < iterations; ++i)
        {
            var bytesSuffled = 0;
            var moveSize     = _moveSize;
            var p            = 0;
            while (true)
            {
                var rBytesShuffle = bufferSize - bytesSuffled;
                if (rBytesShuffle < moveSize)
                    moveSize = rBytesShuffle;
                if (rBytesShuffle <= 0)
                    break;
                Buffer.BlockCopy(buf, p, lBuffer, 0, moveSize);
                lBuffer = _alg.ComputeHash(lBuffer);
                Buffer.BlockCopy(lBuffer, 0, oBuffer, p, moveSize);
                p            += moveSize;
                bytesSuffled += moveSize;
            }
            Buffer.BlockCopy(oBuffer, 0, buf, 0, bufferSize);
        }
        lBuffer.Fill(0);
        oBuffer.Fill(0);
        return buf;
    }
    public ushort[] Mix(ushort[] buf, int iterations = 1000)
    {
        var bb = buf.GetBytes();
        return Mix(bb, iterations).ToUShortArray();
    }
    public uint[] Mix(uint[] buf, int iterations = 1000)
    {
        var bb = buf.GetBytes();
        return Mix(bb, iterations).ToUIntArray();
    }
    public ulong[] Mix(ulong[] buf, int iterations = 1000)
    {
        var bb = buf.GetBytes();
        return Mix(bb, iterations).ToULongArray();
    }
    /// <summary>
    ///     Will round up finalSize to the nearest 8 byte boundary.
    /// </summary>
    /// <param name="ba"></param>
    /// <param name="finalSize"></param>
    /// <returns></returns>
    private static ulong[] ByteArrayToULongArray(byte[] ba, int finalSize)
    {
        var minSize = ba.Length / 8;
        if (finalSize < minSize)
            finalSize = minSize;
        ba = PadULong(ba);
        var os = finalSize / 8;
        if (os * 8 < finalSize)
            os++;
        var result = new ulong[os];
        for (var i = 0; i < ba.Length; i += 8)
            Buffer.BlockCopy(ba, i, result, i, 8);
        return result;
    }
    private static byte[] PadULong(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] = 0x80;
                ba[ba.Length - 2] = 0x80;
                ba[ba.Length - 3] = 0x80;
                ba[ba.Length - 4] = 0x80;
                ba[ba.Length - 5] = 0x80;
                ba[ba.Length - 6] = 0x80;
                ba[ba.Length - 7] = 0x80;
                break;
            case 2:
                Array.Resize(ref ba, ba.Length + 6);
                ba[ba.Length - 1] = 0x80;
                ba[ba.Length - 2] = 0x80;
                ba[ba.Length - 3] = 0x80;
                ba[ba.Length - 4] = 0x80;
                ba[ba.Length - 5] = 0x80;
                ba[ba.Length - 6] = 0x80;
                break;
            case 3:
                Array.Resize(ref ba, ba.Length + 5);
                ba[ba.Length - 1] = 0x80;
                ba[ba.Length - 2] = 0x80;
                ba[ba.Length - 3] = 0x80;
                ba[ba.Length - 4] = 0x80;
                ba[ba.Length - 5] = 0x80;
                break;
            case 4:
                Array.Resize(ref ba, ba.Length + 4);
                ba[ba.Length - 1] = 0x80;
                ba[ba.Length - 2] = 0x80;
                ba[ba.Length - 3] = 0x80;
                ba[ba.Length - 4] = 0x80;
                break;
            case 5:
                Array.Resize(ref ba, ba.Length + 3);
                ba[ba.Length - 1] = 0x80;
                ba[ba.Length - 2] = 0x80;
                ba[ba.Length - 3] = 0x80;
                break;
            case 6:
                Array.Resize(ref ba, ba.Length + 2);
                ba[ba.Length - 1] = 0x80;
                ba[ba.Length - 2] = 0x80;
                break;
            case 7:
                Array.Resize(ref ba, ba.Length + 1);
                ba[ba.Length - 1] = 0x80;
                break;
        }
        return ba;
    }
    private static void Expand(ulong[] x, int iterations = 1)
    {
        var size = x.Length;
        for (var k = 0; k < iterations; ++k)
        for (var i = 0; i < size; ++i)
        {
            ulong n = 0;
            var   j = 0;
            while (j < size)
            {
                n ^= x[j];
                ++j;
            }
            x[i] = (n << 1) | (n >> 56);
        }
    }
    /// <summary>
    ///     ExpandAndMixArray resizes the array by extrusion then mixes the array using a Sha3 one way hash
    /// </summary>
    /// <param name="ba">The buffer</param>
    /// <param name="size">The final desired size</param>
    /// <param name="iterations">The number of iterations to mix the final array</param>
    public byte[] ExpandAndMixArray(byte[] ba, int size, int iterations = 1000)
    {
        var ula = ByteArrayToULongArray(ba, size);
        Expand(ula, 1);
        var array = ula.GetBytes();
        return Mix(array, iterations);
    }
    public ushort[] ExpandAndMixArray(ushort[] ba, int size, int iterations = 1000)
    {
        var bb = ba.GetBytes();
        return ExpandAndMixArray(bb, size, iterations).ToUShortArray();
    }
    public uint[] ExpandAndMixArray(uint[] ba, int size, int iterations = 1000)
    {
        var bb = ba.GetBytes();
        return ExpandAndMixArray(bb, size, iterations).ToUIntArray();
    }
    public ulong[] ExpandAndMixArray(ulong[] ba, int size, int iterations = 1000)
    {
        var bb = ba.GetBytes();
        return ExpandAndMixArray(bb, size, iterations).ToULongArray();
    }
}

EntropyGeneric.cs

Detect Entropy Levels from Primitive Data Arrays

using System;
using System.Collections.Generic;
public class EntropyGeneric<T>
{
    private const    double             NaturalLogOfTwo = 0.69314718055994530941723212145818;
    private readonly Dictionary<T, int> _hist           = new Dictionary<T, int>();
    private          bool               _mapStatus;
    public EntropyGeneric()
    {
        _hist.Clear();
        _mapStatus = false;
    }
    public (double entropy, int perfect) Entropy(T[] s)
    {
        if (_mapStatus)
        {
            _hist.Clear();
            _mapStatus = false;
        }
        foreach (var c in s)
            if (!_hist.ContainsKey(c))
                _hist.Add(c, 1);
            else
                _hist[c] += 1;
        _mapStatus = true;
        var e = 0.0;
        foreach (var v in _hist.Values)
        {
            if (v <= 0)
                continue;
            var r = v             / (double) s.Length;
            e -= r * (Math.Log(r) / NaturalLogOfTwo);
        }
        return (e, GetSize());
    }
    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.GetBytesObject();
    }
    private int GetSize()
    {
        var size = 0;
        switch (Type.GetTypeCode(typeof(T)))
        {
            case TypeCode.Boolean:
                size = 8;
                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 = 96;
                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.");
        }
        return size;
    }
}

ByteArraySegment.cs

Segment a byte array to 16, 32, 64 bit Arrays

using System;
using System.Collections.Generic;
using System.Numerics;
public class ByteArraySegment
{
    public IEnumerable<T[]> SegmentEnum<T>(T[] buffer, int size)
    {
        var idx = 0;
        var ptr = buffer.Length;
        while (ptr >= size)
        {
            var array = new T[size];
            Buffer.BlockCopy(buffer, idx, array, 0, size);
            ptr -= size;
            idx += size;
            yield return array;
        }
    }
    public List<byte[]> SegmentList(byte[] buffer, int size)
    {
        var list = new List<byte[]>(buffer.Length >> 2);
        var idx  = 0;
        var ptr  = buffer.Length;
        while (ptr >= size)
        {
            var _result = new byte[size];
            Buffer.BlockCopy(buffer, idx, _result, 0, size);
            list.Add(_result);
            ptr -= size;
            idx += size;
        }
        return list;
    }
    public char[] SegmentChar(byte[] buffer)
    {
        var len = buffer.Length;
        if (len % 2 != 0)
            throw new Exception("Buffer must be a multiple of 2.");
        var array = new char[len >> 1];
        Buffer.BlockCopy(buffer, 0, array, 0, len);
        return array;
    }
    public short[] Segment16(byte[] buffer)
    {
        var len = buffer.Length;
        if (len % 2 != 0)
            throw new Exception("Buffer must be a multiple of 2.");
        var array = new short[len >> 1];
        Buffer.BlockCopy(buffer, 0, array, 0, len);
        return array;
    }
    public ushort[] SegmentU16(byte[] buffer)
    {
        var len = buffer.Length;
        if (len % 2 != 0)
            throw new Exception("Buffer must be a multiple of 2.");
        var array = new ushort[len >> 1];
        Buffer.BlockCopy(buffer, 0, array, 0, len);
        return array;
    }
    public int[] Segment32(byte[] buffer)
    {
        var len = buffer.Length;
        if (len % 4 != 0)
            throw new Exception("Buffer must be a multiple of 4.");
        var array = new int[len >> 2];
        Buffer.BlockCopy(buffer, 0, array, 0, len);
        return array;
    }
    public float[] SegmentFloat(byte[] buffer)
    {
        var len = buffer.Length;
        if (len % 4 != 0)
            throw new Exception("Buffer must be a multiple of 4.");
        var array = new float[len >> 2];
        Buffer.BlockCopy(buffer, 0, array, 0, len);
        return array;
    }
    public uint[] SegmentU32(byte[] buffer)
    {
        var len = buffer.Length;
        if (len % 4 != 0)
            throw new Exception("Buffer must be a multiple of 4.");
        var array = new uint[len >> 2];
        Buffer.BlockCopy(buffer, 0, array, 0, len);
        return array;
    }
    public long[] Segment64(byte[] buffer)
    {
        var len = buffer.Length;
        if (len % 8 != 0)
            throw new Exception("Buffer must be a multiple of 8.");
        var array = new long[len >> 3];
        Buffer.BlockCopy(buffer, 0, array, 0, len);
        return array;
    }
    public double[] SegmentDouble(byte[] buffer)
    {
        var len = buffer.Length;
        if (len % 8 != 0)
            throw new Exception("Buffer must be a multiple of 8.");
        var array = new double[len >> 3];
        Buffer.BlockCopy(buffer, 0, array, 0, len);
        return array;
    }
    public ulong[] SegmentU64(byte[] buffer)
    {
        var len = buffer.Length;
        if (len % 8 != 0)
            throw new Exception("Buffer must be a multiple of 8.");
        var array = new ulong[len >> 3];
        Buffer.BlockCopy(buffer, 0, array, 0, len);
        return array;
    }
    public BigInteger[] SegmentBI(byte[] buffer, int size)
    {
        var idx  = 0;
        var ptr  = buffer.Length;
        var bi   = new BigInteger[buffer.Length / size];
        var ptr1 = 0;
        while (ptr >= size)
        {
            var array = new byte[size];
            Buffer.BlockCopy(buffer, idx, array, 0, size);
            ptr      -= size;
            idx      += size;
            bi[ptr1++] =  new BigInteger(array);
        }
        return bi;
    }
}