PasswordStretch.cs

Posted on June 13, 2020June 13, 2020Tags , , ,   Leave a comment on PasswordStretch.cs

Password Stretch using Sha3

Example Code:
var b1   = new byte[0];
        var b2   = new byte[0];
        var salt = new byte[0];
        using (var db = new PasswordStretch("1234567890".ToSecureString(), 16))
        {

            b1   = (byte[]) db.GetBytes(0, 64).Clone();
            salt = db.Salt;
        }

        using (var db = new PasswordStretch("1234567891".ToSecureString(), salt))
        {

            b2 = (byte[]) db.GetBytes(0, 64).Clone();
        }
using System;
using System.Security;
using System.Security.Cryptography;
public class PasswordStretch : IDisposable
{
    private const    int         PacketCount = 4;
    private readonly byte[]      _buffer;
    private readonly byte[]      _salt;
    private readonly SHA3Managed _sha;
    public PasswordStretch(SecureString password) : this(password, 0, 1000)
    {
    }
    public PasswordStretch(SecureString password, int saltSize) : this(password, saltSize, 1000)
    {
    }
    public PasswordStretch(SecureString password, int saltSize, int iterations)
    {
        Iterations = iterations;
        var temp = new byte[0];
        if (saltSize != 0)
        {
            var data = new byte[saltSize];
            new RNGCryptoServiceProvider().GetBytes(data);
            _salt   = data;
            _sha    = new SHA3Managed(512);
            _buffer = new byte[_sha.HashLength * PacketCount];
            _sha.TransformBlock(_salt, 0, _salt.Length, null, 0);
            var pwb = password.GetBytes();
            _sha.TransformBlock(pwb, 0, pwb.Length, null, 0);
            _sha.Finalize();
            temp = _sha.HashValue;
        }
        else
        {
            _sha    = new SHA3Managed(512);
            _buffer = new byte[_sha.HashLength * PacketCount];
            temp    = _sha.ComputeHash(password.GetBytes());
        }
        for (var i = 0; i < PacketCount; i++)
        {
            for (var j = 0; j < Iterations; j++)
                temp = _sha.ComputeHash(temp);
            Buffer.BlockCopy(temp, 0, _buffer, i * _sha.HashLength, _sha.HashLength);
        }
    }
    public PasswordStretch(SecureString password, byte[] salt) : this(password, salt, 1000)
    {
    }
    public PasswordStretch(SecureString password, byte[] salt, int iterations = 1000)
    {
        Iterations = iterations;
        _sha       = new SHA3Managed(512);
        _buffer    = new byte[_sha.HashLength * PacketCount];
        _sha.TransformBlock(salt, 0, salt.Length, null, 0);
        var pwb = password.GetBytes();
        _sha.TransformBlock(pwb, 0, pwb.Length, null, 0);
        _sha.Finalize();
        var temp = _sha.HashValue;
        for (var i = 0; i < PacketCount; i++)
        {
            for (var j = 0; j < Iterations; j++)
                temp = _sha.ComputeHash(temp);
            Buffer.BlockCopy(temp, 0, _buffer, i * _sha.HashLength, _sha.HashLength);
        }
    }
    public byte[] Salt
    {
        get
        {
            if (_salt != null)
                return (byte[]) _salt.Clone();
            return default;
        }
    }
    public int Iterations
    {
        get;
    } = 1000;
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    ~PasswordStretch()
    {
        Dispose();
    }
    public byte[] GetBytes(int offset, int psize)
    {
        if (offset + psize > _buffer.Length)
            throw new Exception("Offset and Size Exceed Buffer Length.");
        var passpart = new byte[psize];
        Buffer.BlockCopy(_buffer, offset, passpart, 0, passpart.Length);
        return passpart;
    }
    private void Dispose(bool disposing)
    {
        if (!disposing)
            return;
        if (_sha != null)
            _sha.Dispose();
        if (_buffer != null)
            Array.Clear(_buffer, 0, _buffer.Length);
        if (_salt == null)
            return;
        Array.Clear(_salt, 0, _salt.Length);
    }
}

FixedIntXPrimality.cs

Posted on June 12, 2020Tags , ,   Leave a comment on FixedIntXPrimality.cs

Fixed BigInteger Primality

using System;
using System.Numerics;
using System.Threading;
public class FixedIntXPrimality
{
    private readonly FixedBigInteger _twoSixtyFourPlusIntMax = new FixedBigInteger("18446744073709551616", 64);
    private readonly uint[]          _w0                     = {2};
    private readonly uint[]          _w1                     = {2, 3};
    private readonly uint[]          _w10                    = {2, 3, 5, 7, 11, 13, 17, 19, 23};
    private readonly uint[]          _w11                    = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37};
    private readonly uint[]          _w12                    = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41};
    private readonly uint[]          _w2                     = {31, 73};
    private readonly uint[]          _w3                     = {2, 3, 5};
    private readonly uint[]          _w4                     = {2, 3, 5, 7};
    private readonly uint[]          _w5                     = {2, 7, 61};
    private readonly uint[]          _w6                     = {2, 13, 23, 1662803};
    private readonly uint[]          _w7                     = {2, 3, 5, 7, 11};
    private readonly uint[]          _w8                     = {2, 3, 5, 7, 11, 13};
    private readonly uint[]          _w9                     = {2, 3, 5, 7, 11, 13, 17};
    private readonly int[] LowPrimes =
    {
        2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
        157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313,
        317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491,
        499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677,
        683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881,
        883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997
    };
    private int                                  _bitWidth;
    private FixedBigIntegerRandomNumberGenerator _rng;
    public  int                                  CandidateTried;
    public FixedIntXPrimality(int bitWidth)
    {
        _bitWidth     = bitWidth;
        _rng          = new FixedBigIntegerRandomNumberGenerator(_bitWidth);
        _rng.OddsOnly = true;
        _rng.Unsigned = true;
    }
    public void ResetBitWidth(int bitWidth)
    {
        _bitWidth     = bitWidth;
        _rng          = new FixedBigIntegerRandomNumberGenerator(_bitWidth);
        _rng.OddsOnly = true;
        _rng.Unsigned = true;
    }
    private bool TrialDivision(FixedBigInteger candidate)
    {
        for (var i = 0; i < LowPrimes.Length; i++)
        {
            var p = LowPrimes[i];
            if (i < p)
            {
                if (candidate % p != 0)
                    continue;
                return false;
            }
            break;
        }
        return true;
    }
    private static bool PrimeCheckM10LD(FixedBigInteger n)
    {
        var d1 = (int) (n % 10);
        return d1 == 1 || d1 == 3 || d1 == 7 || d1 == 9;
    }
    private static bool PrimeCheckM6(FixedBigInteger n)
    {
        var d1 = (int) (n % 6);
        return d1 == 1 || d1 == 5;
    }
    public bool IsPrime(uint bi)
    {
        return IsPrime((FixedBigInteger) bi);
    }
    public bool IsPrime(int bi)
    {
        bi = Math.Abs(bi);
        return IsPrime((FixedBigInteger) bi);
    }
    public bool IsPrime(short bi)
    {
        bi = Math.Abs(bi);
        return IsPrime((FixedBigInteger) bi);
    }
    public bool IsPrime(ushort bi)
    {
        return IsPrime((FixedBigInteger) bi);
    }
    public bool IsPrime(byte bi)
    {
        return IsPrime((FixedBigInteger) bi);
    }
    public bool IsPrime(sbyte bi)
    {
        bi = Math.Abs(bi);
        return IsPrime((FixedBigInteger) bi);
    }
    private bool CheckLowPrimes(FixedBigInteger val)
    {
        foreach (var v in LowPrimes)
            if (val == v)
                return true;
        return false;
    }
    public bool IsPrime(FixedBigInteger candidate)
    {
        if (candidate == 1)
            return false;
        if (candidate == 2 || candidate == 3 || candidate == 5)
            return true;
        if (candidate <= 1000)
            return CheckLowPrimes(candidate);
        if (!PrimeCheckM10LD(candidate))
            return false;
        if (!PrimeCheckM6(candidate))
            return false;
        if (!TrialDivision(candidate))
            return false;
        if (candidate < 2047)
        {
            if (!MillerRabin(candidate, _w0))
                return false;
        }
        else if (candidate > 2047 && candidate <= 1373653)
        {
            if (!MillerRabin(candidate, _w1))
                return false;
        }
        else if (candidate > 1373653 && candidate <= 9080191)
        {
            if (!MillerRabin(candidate, _w2))
                return false;
        }
        else if (candidate > 9080191 && candidate <= 25326001)
        {
            if (!MillerRabin(candidate, _w3))
                return false;
        }
        else if (candidate > 25326001 && candidate <= 3215031751)
        {
            if (!MillerRabin(candidate, _w4))
                return false;
        }
        else if (candidate > 3215031751 && candidate <= 4759123141)
        {
            if (!MillerRabin(candidate, _w5))
                return false;
        }
        else if (candidate > 4759123141 && candidate <= 1122004669633)
        {
            if (!MillerRabin(candidate, _w6))
                return false;
        }
        else if (candidate > 1122004669633 && candidate <= 2152302898747)
        {
            if (!MillerRabin(candidate, _w7))
                return false;
        }
        else if (candidate > 2152302898747 && candidate <= 3474749660383)
        {
            if (!MillerRabin(candidate, _w8))
                return false;
        }
        else if (candidate > 3474749660383 && candidate <= 341550071728321)
        {
            if (!MillerRabin(candidate, _w9))
                return false;
        }
        else if (candidate > 341550071728321 && candidate <= 3825123056546413051)
        {
            if (!MillerRabin(candidate, _w10))
                return false;
        }
        else if (candidate > 3825123056546413051 && candidate < _twoSixtyFourPlusIntMax)
        {
            if (!MillerRabin(candidate, _w11))
                return false;
        }
        else if (candidate > _twoSixtyFourPlusIntMax)
        {
            if (!MillerRabin(candidate, _w12))
                return false;
        }
        return true;
    }
    private bool MillerRabin(FixedBigInteger candidate, uint[] w)
    {
        var s = 0;
        var d = candidate - FixedBigInteger.One;
        while ((d & 1) == 0)
        {
            d >>= 1;
            s++;
        }
        if (s == 0)
            return false;
        var nmo = candidate - FixedBigInteger.One;
        for (var i = 0; i < w.Length; ++i)
        {
            var x = BigInteger.ModPow(w[i], (BigInteger) d, (BigInteger) candidate);
            if (x == 1 || x == nmo)
                continue;
            for (var r = 1; r < s; ++r)
            {
                x = BigInteger.ModPow(x, 2, (BigInteger) candidate);
                if (x == 1)
                    return false;
                if (x == nmo)
                    break;
            }
            if (x == nmo)
                continue;
            return false;
        }
        return true;
    }
    public FixedBigInteger GetPrimeNumber(bool fixedWidth = false)
    {
        var bw = 0;
        if (!fixedWidth)
        {
            var MaxBytes = _bitWidth >> 3;
            var bwb      = new byte[2];
            _rng.GetBytes(bwb);
            bw = bwb[0] % MaxBytes + 1;
            if (bw < 1)
                bw = 1;
        }
        else
        {
            bw = _bitWidth >> 3;
        }
        var buffer = new byte[bw];
        var n      = new FixedBigInteger(0, 0);
        CandidateTried = 0;
        var btrd = new Thread(() =>
        {
            while (true)
            {
                CandidateTried++;
                _rng.GetBytes(buffer);
                n = new FixedBigInteger(buffer, _bitWidth) | 1;
                if (n == 1)
                    continue;
                if (n > n.MaxValue)
                    continue;
                if (IsPrime(n))
                    break;
            }
        }) {Priority = ThreadPriority.Highest};
        btrd.Start();
        btrd.Join();
        return n;
    }
}

TextBinaryFileId.cs

Posted on June 11, 2020Tags , , , ,   Leave a comment on TextBinaryFileId.cs

Determine Byte Array Binary or Text

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
public class TextBinaryFileId
{
    private readonly BoyerMoore                 _boyerMoore4Null = new BoyerMoore(new byte[] {0, 0, 0, 0});
    public           Dictionary<string, string> BinaryFiles      = new Dictionary<string, string>();
    public           Dictionary<string, string> EncodingFiles    = new Dictionary<string, string>();
    public           Dictionary<string, double> TextFiles        = new Dictionary<string, double>();
    public bool IsBlockText(byte[] BinData, double ConfidenceThreshold = 25)
    {
        if (BinData.Length == 0)
            return false;
        if (_boyerMoore4Null.Search(BinData) != -1)
            return false;
        var enc     = GetEncoding(BinData);
        var CcCount = BinData.AsParallel().Count(b => !IsValidTextByte(b, !(enc == Encoding.UTF8 || enc == Encoding.UTF7 || enc == Encoding.ASCII)));
        var asp     = (double) CcCount / BinData.Length * 100d;
        return !(asp > ConfidenceThreshold);
    }
    public byte[] ReadBytes(string path)
    {
        try
        {
            var ba  = File.ReadAllBytes(path);
            var enc = GetEncoding(ba);
            EncodingFiles.Add(path, enc.EncodingName);
            if (Equals(enc, Encoding.UTF7) || Equals(enc, Encoding.UTF8) || Equals(enc, Encoding.ASCII)) return ba;
            if (Equals(enc, Encoding.Unicode))
            {
                var len  = ba.Length - 2;
                var blen = len / 2;
                if (blen * 2 < len) blen++;
                var b = new byte[blen];
                for (int i = 2, j = 0; i < ba.Length && j < blen; i += 2, ++j)
                    b[j] = ba[i];
                return b;
            }
            if (Equals(enc, Encoding.UTF32))
            {
                var len1  = ba.Length - 4;
                var blen1 = len1 / 4;
                if (blen1 * 4 < len1)
                    blen1++;
                var b1 = new byte[blen1];
                for (int i = 4, j = 0; i < ba.Length && j < blen1; i += 4, ++j)
                    b1[j] = ba[i];
                return b1;
            }
            return ba;
        }
        catch (Exception ex)
        {
            ExceptionLog.ExLog(ex, "ReadBytes", "ReadBytes");
        }
        return null;
    }
    public bool IsText(string path, bool TestEntireFile = false, double ConfidenceThreshold = 100, bool TestEncoding = true)
    {
        var    Reason = "None";
        var    isText = true;
        double asp    = 0;
        using (var fileStream = File.OpenRead(path))
        {
            var WindowSize = 0l;
            if (TestEntireFile)
            {
                WindowSize = fileStream.Length;
            }
            else
            {
                WindowSize = 512;
                if (WindowSize > fileStream.Length)
                    WindowSize = fileStream.Length;
            }
            if (fileStream.Length == 0)
            {
                BinaryFiles.Add(path, "Zero Length File.");
                return false;
            }
            var BinData       = new byte[WindowSize];
            var BinDataLength = fileStream.Read(BinData, 0, BinData.Length);
            fileStream.Seek(0, SeekOrigin.Begin);
            if (fileStream.Length < 4)
            {
                var r = BinData.All(b => IsValidTextByte(b));
                if (!r)
                    BinaryFiles.Add(path, "Length 4 file Contains invalid Characters.");
                return r;
            }
            if (_boyerMoore4Null.Search(BinData) != -1)
            {
                Reason = "4 Sequential Nulls Found within File.";
                isText = false;
            }
            if (isText)
            {
                var enc = GetEncoding(BinData);
                if (TestEncoding)
                {
                    var TextData = new char[WindowSize];
                    var eMatches = 0;
                    using (var streamReader = new StreamReader(fileStream))
                    {
                        streamReader.Read(TextData, 0, TextData.Length);
                    }
                    using (var memoryStream = new MemoryStream())
                    {
                        using (var streamWriter = new StreamWriter(memoryStream, enc))
                        {
                            streamWriter.Write(TextData);
                            streamWriter.Flush();
                            var memoryBuffer = memoryStream.GetBuffer();
                            for (var i = 0; i < BinDataLength /*&& isText*/; i++)
                                if (BinData[i] == memoryBuffer[i])
                                    eMatches++;
                            //if(!isText)
                            //    Reason = $"Encoding Mismatch Found at position: {i}";
                            var er = (double) eMatches / BinDataLength * 100d;
                            if ((int) er < 99)
                            {
                                isText = false;
                                Reason = $"Encoding Mismatch: {er:0.0}";
                            }
                        }
                    }
                }
                if (isText)
                {
                    double CcCount = BinData.AsParallel().Count(b => !IsValidTextByte(b, !(enc == Encoding.UTF8 || enc == Encoding.UTF7 || enc == Encoding.ASCII)));
                    asp = CcCount / BinData.Length * 100d;
                    if (asp > ConfidenceThreshold)
                    {
                        Reason = $"Confidence threshold {ConfidenceThreshold:0.0} Exceeded: {asp:0.0}";
                        isText = false;
                    }
                }
            }
        }
        if (isText)
            TextFiles.Add(path, asp.TruncateToDecimalPlace(1));
        else
            BinaryFiles.Add(path, Reason);
        return isText;
    }
    public static Encoding GetEncoding(byte[] Data)
    {
        if (Data == null)
            throw new Exception("Array cannot be null.");
        if (Data.Length < 2)
            return Encoding.Default;
        if (Data[0] == 0xff && Data[1] == 0xfe)
            return Encoding.Unicode;
        if (Data[0] == 0xfe && Data[1] == 0xff)
            return Encoding.BigEndianUnicode;
        if (Data.Length < 3)
            return Encoding.Default;
        if (Data[0] == 0xef && Data[1] == 0xbb && Data[2] == 0xbf)
            return Encoding.UTF8;
        if (Data[0] == 0x2b && Data[1] == 0x2f && Data[2] == 0x76)
            return Encoding.UTF7;
        if (Data.Length < 4)
            return Encoding.Default;
        if (Data[0] == 0xff && Data[1] == 0xfe && Data[2] == 0 && Data[3] == 0)
            return Encoding.UTF32;
        return Encoding.Default;
    }
    private static bool IsValidTextByte(byte _byte, bool IncludeNull = false)
    {
        if (IncludeNull)
            if (_byte == 0x00)
                return true;
        if (_byte == 0x0A || _byte == 0x0D || _byte == 0x09 || _byte >= 0x20 && _byte <= 0x2F || _byte >= 0x30 && _byte <= 0x39 || _byte >= 0x3A && _byte <= 0x40 || _byte >= 0x41 && _byte <= 0x5A || _byte >= 0x5B && _byte <= 0x60 || _byte >= 0x61 && _byte <= 0x7A || _byte >= 0x7B && _byte <= 0x7E)
            return true;
        return false;
    }
}

Writer.cs

Posted on June 10, 2020June 11, 2020Tags , ,   Leave a comment on Writer.cs

Simplified Binary Writer

Example Code:

using System;
using System.IO;
using System.Numerics;
using System.Text;
/// <inheritdoc />
/// <summary>
///     Alternate Binary Writer created to enhance usability and ease coding complexity.
/// </summary>
public class Writer : IDisposable
{
    /// <inheritdoc />
    /// <summary>
    ///     Initializes a new instance of the Writer class based on a specified path name, a default FileMode of Create, and
    ///     defaulting to UTF-8 encoding.
    /// </summary>
    public Writer(string path) : this(path, FileMode.Create, new UTF8Encoding(false, true))
    {
    }
    /// <inheritdoc />
    /// <summary>
    ///     Initializes a new instance of the Writer class based on a specified path name, a specified FileMode and defaulting
    ///     to UTF-8 encoding.
    /// </summary>
    public Writer(string path, FileMode fm) : this(path, fm, new UTF8Encoding(false, true))
    {
    }
    /// <summary>
    ///     Initializes a new instance of the Writer class based on a specified path name, a specified FileMode and a specified
    ///     encoding.
    /// </summary>
    public Writer(string path, FileMode fm, Encoding encoding)
    {
        if (string.IsNullOrEmpty(path))
            throw new Exception($"Path {path} cannot be null or empty.");
        BaseMode = fm;
        try
        {
            if (File.Exists(path))
                File.SetAttributes(path, File.GetAttributes(path) | FileAttributes.Normal);
            BaseStream = new FileStream(path, BaseMode, FileAccess.Write);
            if (BaseStream?.CanWrite == true)
                BaseWriter = new BinaryWriter(BaseStream, encoding, true);
            else throw new Exception($"The FileStream for path:{path} is null.");
        }
        catch (Exception e)
        {
            throw new Exception($"Error: {e.Message}");
        }
    }
    public Writer(Stream stream) : this(stream, new UTF8Encoding(false, true))
    {
    }
    public Writer(Stream strm, Encoding encoding)
    {
        try
        {
            if (strm?.CanWrite == true)
                BaseWriter = new BinaryWriter(strm, encoding, true);
            else throw new Exception("The Stream is null.");
        }
        catch (Exception e)
        {
            throw new Exception($"Error: {e.Message}");
        }
    }
    /// <summary>
    ///     Expose the underlying BinaryWriter
    /// </summary>
    public BinaryWriter BaseWriter { get; }
    /// <summary>
    ///     Expose the underlying FileMode
    /// </summary>
    public FileMode BaseMode { get; }
    /// <summary>
    ///     Expose the underlying FileStream
    /// </summary>
    public FileStream BaseStream { get; }
    /// <summary>
    ///     Each time a primitive is written there is one additional integer written to signify its type.
    ///     This can be used to compute the final size of the stream bytes needed.
    /// </summary>
    public static int PrimitiveOverHead => sizeof(int);
    /// <summary>
    ///     Each time a array is written there are two additional integers written one to signify its type and the other its
    ///     size.
    ///     This can be used to compute the final size of the stream bytes needed.
    /// </summary>
    public static int ArrayOverHead => sizeof(int) * 2;
    public void Dispose()
    {
        if (BaseStream == null) return;
        BaseStream.Flush();
        BaseStream.Dispose();
    }
    /// <summary>
    ///     Sets the position to offset relative to origin within the stream.
    /// </summary>
    public long Seek(int offset, SeekOrigin origin)
    {
        return BaseStream.Seek(offset, origin);
    }
    public void WriteBool(bool value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.Boolean);
        BaseWriter.Write(value);
    }
    public void WriteChar(char value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.Character);
        BaseWriter.Write(value);
    }
    public void WriteByte(byte value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.Byte);
        BaseWriter.Write(value);
    }
    public void WriteSByte(sbyte value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.ShortByte);
        BaseWriter.Write(value);
    }
    public void WriteShort(short value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.Short);
        BaseWriter.Write(value);
    }
    public void WriteUShort(ushort value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.UnsignedShort);
        BaseWriter.Write(value);
    }
    public void WriteInt(int value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.Integer);
        BaseWriter.Write(value);
    }
    public void WriteUInt(uint value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.UnsignedInteger);
        BaseWriter.Write(value);
    }
    public void WriteLOng(long value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.Long);
        BaseWriter.Write(value);
    }
    public void WriteULong(ulong value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.UnsignedLong);
        BaseWriter.Write(value);
    }
    public void WriteString(string value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.String);
        BaseWriter.Write(value);
    }
    public void WriteFloat(float value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.Float);
        BaseWriter.Write(value);
    }
    public void WriteDouble(double value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.Double);
        BaseWriter.Write(value);
    }
    public void WriteDecimal(decimal value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.Decimal);
        BaseWriter.Write(value);
    }
    public void WriteBigInteger(BigInteger value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.BigInteger);
        WriteBytes(value.ToByteArray());
    }
    public void WriteBigRational(BigRational value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.BigRational);
        var Num = value.Numerator.ToByteArray();
        var Den = value.Denominator.ToByteArray();
        WriteBytes(Num);
        WriteBytes(Den);
    }
    public void WriteBools(bool[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.BooleanArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteChars(char[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.CharacterArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteBytes(byte[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.ByteArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteSBytes(sbyte[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.ShortByteArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteShorts(short[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.ShortArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteUShorts(ushort[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.UnsignedShortArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteInts(int[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.IntegerArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteUInts(uint[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.UnsignedIntegerArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteLongs(long[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.LongArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteULongs(ulong[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.UnsignedLongArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteStrings(string[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.StringArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteFloats(float[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.FloatArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteDoubles(double[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.DoubleArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteDecimals(decimal[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.DecimalArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            BaseWriter.Write(v);
    }
    public void WriteBigIntegers(BigInteger[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.BigIntegerArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            WriteBigInteger(v);
    }
    public void WriteBigRationals(BigRational[] value)
    {
        BaseWriter.Write((int) Rwtypes.Readerwritertypes.BigRationalArray);
        var len = value.Length;
        BaseWriter.Write(len);
        foreach (var v in value)
            WriteBigRational(v);
    }
}

Reader.cs

Posted on June 10, 2020June 11, 2020Tags ,   Leave a comment on Reader.cs

Simplified Binary Reader

Example Code:

using System;
using System.IO;
using System.Numerics;
using System.Text;
/// <inheritdoc />
/// <summary>
///     Alternate Binary Reader created to ease usability and complexity of coding.
/// </summary>
public class Reader : IDisposable
{
    /// <inheritdoc />
    /// <summary>
    ///     Initializes a new instance of the Reader class based on a specified path name, and defaulting to UTF-8 encoding.
    /// </summary>
    public Reader(string path) : this(path, new UTF8Encoding(false, true))
    {
    }
    /// <summary>
    ///     Initializes a new instance of the Reader class based on a specified path name, a specified encoding.
    /// </summary>
    public Reader(string path, Encoding encoding)
    {
        if (string.IsNullOrEmpty(path))
            throw new Exception($"Path {path} cannot be null or empty.");
        try
        {
            File.SetAttributes(path, File.GetAttributes(path) | FileAttributes.Normal);
            BaseStream = new FileStream(path, FileMode.Open, FileAccess.Read);
            if (BaseStream?.CanRead == true)
                BaseReader = new BinaryReader(BaseStream, encoding);
            else throw new Exception($"The FileStream for path:{path} is null.");
        }
        catch (Exception e)
        {
            throw new Exception($"Error: {e.Message}");
        }
    }
    public Reader(Stream strm) : this(strm, new UTF8Encoding(false, true))
    {
    }
    public Reader(Stream strm, Encoding encoding)
    {
        try
        {
            if (strm?.CanRead == true)
                BaseReader = new BinaryReader(strm, encoding);
            else throw new Exception("The Stream is null.");
        }
        catch (Exception e)
        {
            throw new Exception($"Error: {e.Message}");
        }
    }
    /// <summary>
    ///     Expose the underlying BinaryReader
    /// </summary>
    public BinaryReader BaseReader { get; }
    /// <summary>
    ///     Expose the underlying FileStream
    /// </summary>
    public FileStream BaseStream { get; }
    /// <summary>
    ///     Each time a primitive is written there is one additional integer written to signify its type.
    ///     This can be used to compute the final size of the stream bytes needed.
    /// </summary>
    public static int PrimitiveOverHead => sizeof(int);
    /// <summary>
    ///     Each time a array is written there are two additional integers written one to signify its type and the other its
    ///     size.
    ///     This can be used to compute the final size of the stream bytes needed.
    /// </summary>
    public static int ArrayOverHead => sizeof(int) * 2;
    public void Dispose()
    {
        BaseStream?.Dispose();
    }
    /// <summary>
    ///     Sets the position to offset relative to origin within the stream.
    /// </summary>
    public long Seek(int offset, SeekOrigin origin)
    {
        return BaseStream.Seek(offset, origin);
    }
    /// <summary>
    ///     A wrapper for PeekChar of BinaryReader underling class.
    /// </summary>
    public int PeekChar()
    {
        return BaseReader.PeekChar();
    }
    public bool ReadBool()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary boolean value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Boolean)
            throw new Exception($"Boolean value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadBoolean();
    }
    public char ReadChar()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Char value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Character)
            throw new Exception($"Character value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadChar();
    }
    public byte ReadByte()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Byte value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Byte)
            throw new Exception($"Byte value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadByte();
    }
    public sbyte ReadSByte()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary short byte value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.ShortByte)
            throw new Exception($"Short Byte value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadSByte();
    }
    public short ReadShort()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Short value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Short)
            throw new Exception($"Short value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadInt16();
    }
    public ushort ReadUShort()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Unsigned Short value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.UnsignedShort)
            throw new Exception($"Unsigned Short value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadUInt16();
    }
    public int ReadInt()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Integer value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Integer)
            throw new Exception($"Integer value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadInt32();
    }
    public uint ReadUInt()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Unsigned Integer value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.UnsignedInteger)
            throw new Exception($"Unsigned Integer value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadUInt32();
    }
    public long ReadLong()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Long value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Long)
            throw new Exception($"Long value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadInt64();
    }
    public ulong ReadULong()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Unsigned Long value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.UnsignedLong)
            throw new Exception($"Unsigned Long value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadUInt64();
    }
    public string ReadString()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary String value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.String)
            throw new Exception($"String value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadString();
    }
    public float ReadFloat()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Float value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Float)
            throw new Exception($"Float value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadSingle();
    }
    public double ReadDouble()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Double value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Double)
            throw new Exception($"Double value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadDouble();
    }
    public decimal ReadDecimal()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary Decimal value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.Decimal)
            throw new Exception($"Decimal value read requested '{Rwtypes.GetType(t)}' value found.");
        return BaseReader.ReadDecimal();
    }
    public BigInteger ReadBigInteger()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary BigInteger value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.BigInteger)
            throw new Exception($"BigInteger value read requested '{Rwtypes.GetType(t)}' value found.");
        return new BigInteger(ReadBytes());
    }
    public BigRational ReadBigRational()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary BigRational value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.BigRational)
            throw new Exception($"BigRational value read requested '{Rwtypes.GetType(t)}' value found.");
        var Num = new BigInteger(ReadBytes());
        var Den = new BigInteger(ReadBytes());
        return new BigRational(Num, Den);
    }
    public bool[] ReadBools()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary boolean array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.BooleanArray)
            throw new Exception($"Boolean Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new bool[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadBoolean();
        return arr;
    }
    public char[] ReadChars()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary char array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.CharacterArray)
            throw new Exception($"Character array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new char[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadChar();
        return arr;
    }
    public byte[] ReadBytes()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary byte array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.ByteArray)
            throw new Exception($"Byte Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new byte[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadByte();
        return arr;
    }
    public sbyte[] ReadSBytes()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary sbyte array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.ShortByteArray)
            throw new Exception($"Short Byte Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new sbyte[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadSByte();
        return arr;
    }
    public short[] ReadShorts()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary short array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.ShortArray)
            throw new Exception($"Short Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new short[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadInt16();
        return arr;
    }
    public ushort[] ReadUShorts()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary unsigned short array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.UnsignedShortArray)
            throw new Exception($"Unsigned Short Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new ushort[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadUInt16();
        return arr;
    }
    public int[] ReadInts()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary integer array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.IntegerArray)
            throw new Exception($"Integer Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new int[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadInt32();
        return arr;
    }
    public uint[] ReadUInts()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary unsigned integer array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.UnsignedInteger)
            throw new Exception($"Unsigned Integer Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new uint[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadUInt32();
        return arr;
    }
    public long[] ReadLongs()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary long array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.LongArray)
            throw new Exception($"Long Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new long[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadInt64();
        return arr;
    }
    public ulong[] ReadULongs()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary unsigned long array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.UnsignedLongArray)
            throw new Exception($"Unsigned Long Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new ulong[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadUInt64();
        return arr;
    }
    public string[] ReadStrings()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary string array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.StringArray)
            throw new Exception($"String Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new string[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadString();
        return arr;
    }
    public float[] ReadFloats()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary float array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.FloatArray)
            throw new Exception($"Float Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new float[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadSingle();
        return arr;
    }
    public double[] ReadDoubles()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary double array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.DoubleArray)
            throw new Exception($"Double Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new double[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadDouble();
        return arr;
    }
    public decimal[] ReadDecimals()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary decimal array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.DecimalArray)
            throw new Exception($"Decimal Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new decimal[len];
        for (var i = 0; i < len; ++i)
            arr[i] = BaseReader.ReadDecimal();
        return arr;
    }
    public BigInteger[] ReadBigIntegers()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary BigInteger array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.BigIntegerArray)
            throw new Exception($"BigInteger Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new BigInteger[len];
        for (var i = 0; i < len; ++i)
            arr[i] = ReadBigInteger();
        return arr;
    }
    public BigRational[] ReadBigRationals()
    {
        if (BaseReader.PeekChar() == -1)
            throw new Exception("Primary BigRational array value does not exist or can not be read.");
        var t = BaseReader.ReadInt32();
        if (t != (int) Rwtypes.Readerwritertypes.BigRationalArray)
            throw new Exception($"BigRational Array value read requested '{Rwtypes.GetType(t)}' value found.");
        var len = BaseReader.ReadInt32();
        var arr = new BigRational[len];
        for (var i = 0; i < len; ++i)
            arr[i] = ReadBigRational();
        return arr;
    }
}

KeccakSpongeManaged.cs

Posted on June 8, 2020  Leave a comment on KeccakSpongeManaged.cs

Keccak Sponge (Sha3) Checked

using System;
using System.Runtime.CompilerServices;
[Serializable]
public class SHA3Managed : HashAlgorithmEx
{
    private readonly KeccakSpongeManaged ksm;
    public SHA3Managed(int size, ulong[] seed = null) : this(size, 24, seed)
    {
    }
    public SHA3Managed(int size) : this(size, 24)
    {
    }
    public SHA3Managed() : this(512, 24)
    {
    }
    public SHA3Managed(int size, int rounds = 24, ulong[] seed = null)
    {
        if (rounds > 24)
            throw new Exception($"Maximum rounds allowed is {24}");
        var MaxBR     = (64 >> 3) * 25;
        var sizeBytes = size >> 3;
        var rateBytes = MaxBR - (sizeBytes << 1);
        var MaxSize   = ((MaxBR - 8)       >> 1) << 3;
        if (rateBytes < 8)
            throw new Exception($"Maximum size allowed is {MaxSize} Bits with {64} bit Width specified. Specified Size is {size} Bits.");
        var outputLength = size >> 3;
        ksm           = new KeccakSpongeManaged(rateBytes, 200 - rateBytes, KeccakSpongeManaged.KeccakDelimiter, outputLength, seed);
        ksm.Rounds    = rounds;
        HashSizeValue = size;
    }
    public int HashLength => ksm.HashLength;
    public override void Initialize()
    {
        ksm.Initialize();
    }
    protected override void HashCore(byte[] array, int ibStart, int cbSize)
    {
        Initialize();
        ksm.Absorb(array, ibStart, cbSize);
    }
    protected override byte[] HashFinal()
    {
        return ksm.Squeeze();
    }
}
[Serializable]
public class KeccakSpongeManaged
{
    public const     int KeccakDelimiter = 6;
    public const     int ShakeDelimiter  = 31;
    private readonly int _delimiter;
    private readonly int _outputLength;
    private readonly int _rateBytes;
    private readonly ulong[] _roundConstants =
    {
        0x0000000000000001,
        0x0000000000008082,
        0x800000000000808A,
        0x8000000080008000,
        0x000000000000808B,
        0x0000000080000001,
        0x8000000080008081,
        0x8000000000008009,
        0x000000000000008A,
        0x0000000000000088,
        0x0000000080008009,
        0x000000008000000A,
        0x000000008000808B,
        0x800000000000008B,
        0x8000000000008089,
        0x8000000000008003,
        0x8000000000008002,
        0x8000000000000080,
        0x000000000000800A,
        0x800000008000000A,
        0x8000000080008081,
        0x8000000000008080,
        0x0000000080000001,
        0x8000000080008008
    };
    private readonly ulong[] _seed;
    private          int     _blockSize;
    private          int     _input;
    private          int     _output;
    private          byte[]  _result;
    private          ulong[] _state;
    public           int     HashLength;
    public           int     Rounds = 24;
    public KeccakSpongeManaged(int rateBytes, int capacityBytes, int delimiter, int outputLength, ulong[] seed)
    {
        if (rateBytes + capacityBytes != 200 || (uint) (rateBytes % 8) > 0U)
            throw new ArgumentException($"rateBytes {rateBytes} + capacityBytes {capacityBytes}={rateBytes + capacityBytes} must be 200 or {rateBytes} must be a multiple of 8");
        _rateBytes    = rateBytes;
        _delimiter    = delimiter;
        _outputLength = outputLength;
        HashLength    = outputLength;
        _seed         = seed;
    }
    public void Initialize()
    {
        _blockSize = 0;
        _input     = 0;
        _output    = 0;
        _state     = new ulong[25];
        _result    = new byte[_outputLength];
        if (_seed != null && _seed[0] != 0)
        {
            for (var i = 0; i < _seed.Length && i < _state.Length; ++i)
                _state[i] = _seed[i];
            Permute(_state);
        }
    }
    public void Absorb(byte[] array, int start, int size)
    {
        while (size > 0)
        {
            _blockSize = Math.Min(size, _rateBytes);
            for (var index = start; index < _blockSize; ++index)
            {
                var num = Convert.ToByte(Buffer.GetByte(_state, index) ^ array[index + _input]);
                Buffer.SetByte(_state, index, num);
            }
            _input += _blockSize;
            size   -= _blockSize;
            if (_blockSize == _rateBytes)
            {
                Permute(_state);
                _blockSize = 0;
            }
        }
    }
    public byte[] Squeeze()
    {
        Buffer.SetByte(_state, _blockSize, Convert.ToByte(Buffer.GetByte(_state, _blockSize) ^ _delimiter));
        if ((_delimiter & 128) != 0 && _blockSize == _rateBytes - 1)
            Permute(_state);
        Buffer.SetByte(_state, _rateBytes - 1, Convert.ToByte(Buffer.GetByte(_state, _rateBytes - 1) ^ 128));
        Permute(_state);
        var outputLength = _outputLength;
        while (outputLength > 0)
        {
            _blockSize = Math.Min(outputLength, _rateBytes);
            Buffer.BlockCopy(_state, 0, _result, _output, _blockSize);
            _output      += _blockSize;
            outputLength -= _blockSize;
            if (outputLength > 0)
                Permute(_state);
        }
        return _result;
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    private void Permute(ulong[] state)
    {
        for (var round = 0; round < Rounds; ++round)
        {
            Theta(out var C0, state, out var C1, out var C2, out var C3, out var C4);
            RhoPi(state);
            Chi(ref C0, state, ref C1, ref C2, ref C3, ref C4);
            Iota(round, state);
        }
    }
    private static void Theta(out ulong C0, ulong[] state, out ulong C1, out ulong C2, out ulong C3, out ulong C4)
    {
        C0 = state[0] ^ state[5] ^ state[10] ^ state[15] ^ state[20];
        C1 = state[1] ^ state[6] ^ state[11] ^ state[16] ^ state[21];
        C2 = state[2] ^ state[7] ^ state[12] ^ state[17] ^ state[22];
        C3 = state[3] ^ state[8] ^ state[13] ^ state[18] ^ state[23];
        C4 = state[4] ^ state[9] ^ state[14] ^ state[19] ^ state[24];
        var D0 = Rol(C1, 1) ^ C4;
        var D1 = Rol(C2, 1) ^ C0;
        var D2 = Rol(C3, 1) ^ C1;
        var D3 = Rol(C4, 1) ^ C2;
        var D4 = Rol(C0, 1) ^ C3;
        state[0]  ^= D0;
        state[5]  ^= D0;
        state[10] ^= D0;
        state[15] ^= D0;
        state[20] ^= D0;
        state[1]  ^= D1;
        state[6]  ^= D1;
        state[11] ^= D1;
        state[16] ^= D1;
        state[21] ^= D1;
        state[2]  ^= D2;
        state[7]  ^= D2;
        state[12] ^= D2;
        state[17] ^= D2;
        state[22] ^= D2;
        state[3]  ^= D3;
        state[8]  ^= D3;
        state[13] ^= D3;
        state[18] ^= D3;
        state[23] ^= D3;
        state[4]  ^= D4;
        state[9]  ^= D4;
        state[14] ^= D4;
        state[19] ^= D4;
        state[24] ^= D4;
    }
    private static void RhoPi(ulong[] state)
    {
        var a = Rol(state[1], 1);
        state[1]  = Rol(state[6],  44);
        state[6]  = Rol(state[9],  20);
        state[9]  = Rol(state[22], 61);
        state[22] = Rol(state[14], 39);
        state[14] = Rol(state[20], 18);
        state[20] = Rol(state[2],  62);
        state[2]  = Rol(state[12], 43);
        state[12] = Rol(state[13], 25);
        state[13] = Rol(state[19], 8);
        state[19] = Rol(state[23], 56);
        state[23] = Rol(state[15], 41);
        state[15] = Rol(state[4],  27);
        state[4]  = Rol(state[24], 14);
        state[24] = Rol(state[21], 2);
        state[21] = Rol(state[8],  55);
        state[8]  = Rol(state[16], 45);
        state[16] = Rol(state[5],  36);
        state[5]  = Rol(state[3],  28);
        state[3]  = Rol(state[18], 21);
        state[18] = Rol(state[17], 15);
        state[17] = Rol(state[11], 10);
        state[11] = Rol(state[7],  6);
        state[7]  = Rol(state[10], 3);
        state[10] = a;
    }
    private void Iota(int round, ulong[] state)
    {
        state[0] ^= _roundConstants[round];
    }
    private static void Chi(ref ulong C0, ulong[] state, ref ulong C1, ref ulong C2, ref ulong C3, ref ulong C4)
    {
        for (var index = 0; index < 25; index += 5)
        {
            C0               = state[index]     ^ (~state[1 + index] & state[2 + index]);
            C1               = state[1 + index] ^ (~state[2 + index] & state[3 + index]);
            C2               = state[2 + index] ^ (~state[3 + index] & state[4 + index]);
            C3               = state[3 + index] ^ (~state[4 + index] & state[index]);
            C4               = state[4 + index] ^ (~state[index]     & state[1 + index]);
            state[index]     = C0;
            state[1 + index] = C1;
            state[2 + index] = C2;
            state[3 + index] = C3;
            state[4 + index] = C4;
        }
    }
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    private static ulong Rol(ulong x, byte y)
    {
        return (x << y) | (x >> (64 - y));
    }
}

BMPartialPatternSearch.cs

Posted on June 7, 2020  Leave a comment on BMPartialPatternSearch.cs

Boyer Moore Partial Pattern Search

using System;
using System.Collections.Generic;
public class BMPartialPatternSearch
{
    public int MinimumSearchLength;
    public BMPartialPatternSearch(int min = 5)
    {
        MinimumSearchLength = min;
    }
    public (byte[] partialPattern, int idx) SearchPartial(byte[] pattern, byte[] searchArray)
    {
        var bm   = new BoyerMoore(pattern);
        var len  = pattern.Length;
        var tree = new List<byte[]>();
        if (len < MinimumSearchLength)
            throw new Exception("Search Pattern less than minimum search length.");
        var offset = 0;
        var wl     = MinimumSearchLength;
        do
        {
            var tpat = new byte[wl];
            Array.Copy(pattern, offset, tpat, 0, wl);
            tree.Add(tpat);
            bm.SetPattern(tpat);
            var idx = bm.Search(searchArray);
            if (idx != -1)
                return (tpat, idx);
            if (offset + wl >= len)
            {
                offset = 0;
                wl++;
                continue;
            }
            offset++;
        } while (wl != len + 1);
        return (pattern, -1);
    }
    public List<(byte[] partialPattern, int idx)> SearchPartialFirst(byte[] pattern, byte[] searchArray)
    {
        var bm   = new BoyerMoore(pattern);
        var len  = pattern.Length;
        var lst  = new List<(byte[] partialPattern, int idx)>();
        var tree = new List<byte[]>();
        if (len < MinimumSearchLength)
            throw new Exception("Search Pattern less than minimum search length.");
        var offset = 0;
        var wl     = MinimumSearchLength;
        do
        {
            var tpat = new byte[wl];
            Array.Copy(pattern, offset, tpat, 0, wl);
            tree.Add(tpat);
            bm.SetPattern(tpat);
            var idx = bm.Search(searchArray);
            if (idx != -1)
                lst.Add((tpat, idx));
            if (offset + wl >= len)
            {
                offset = 0;
                wl++;
                continue;
            }
            offset++;
        } while (wl != len + 1);
        return new List<(byte[] partialPattern, int idx)> {(pattern, -1)};
    }
    public List<(byte[] partialPattern, int idx)> SearchPartialAll(byte[] pattern, byte[] searchArray)
    {
        var bm   = new BoyerMoore(pattern);
        var len  = pattern.Length;
        var lst  = new List<(byte[] partialPattern, int idx)>();
        var tree = new List<byte[]>();
        if (len < MinimumSearchLength)
            throw new Exception("Search Pattern less than minimum search length.");
        var offset = 0;
        var wl     = MinimumSearchLength;
        do
        {
            var tpat = new byte[wl];
            Array.Copy(pattern, offset, tpat, 0, wl);
            tree.Add(tpat);
            bm.SetPattern(tpat);
            var idxl = bm.SearchAll(searchArray);
            if (idxl.Item1.Count > 0)
                foreach (var idx in idxl.Item1)
                    lst.Add((tpat, idx));
            if (offset + wl >= len)
            {
                offset = 0;
                wl++;
                continue;
            }
            offset++;
        } while (wl != len + 1);
        return lst;
    }
    public static Dictionary<string, int> SearchPartialSubSet(byte[] searchArray, int startLength, int endLength)
    {
        var pattern = (byte[]) searchArray.Clone();
        var bm      = new BoyerMoore(pattern);
        var pLen    = pattern.Length;
        var lst     = new Dictionary<string, int>();
        var tree    = new List<byte[]>();
        if (pLen < endLength)
            throw new Exception("Search Pattern less than minimum search length.");
        var offset = 0;
        var wl     = startLength;
        do
        {
            var tpat = new byte[wl];
            Array.Copy(pattern, offset, tpat, 0, wl);
            tree.Add(tpat);
            bm.SetPattern(tpat);
            var idxl = bm.SearchAll(searchArray);
            if (idxl.Item1.Count > 1)
            {
                var sapat = tpat.ToHexString();
                if (!lst.ContainsKey(sapat))
                    lst.Add(sapat, idxl.Item1.Count);
            }
            if (offset + wl >= pLen)
            {
                offset = 0;
                wl++;
                if (wl > endLength)
                    break;
                continue;
            }
            offset++;
        } while (wl != pLen + 1);
        return lst;
    }
    public static Dictionary<string, int> SearchPartialSubSet(byte[] searchArray1, byte[] searchArray2, int startLength, int endLength)
    {
        var bm   = new BoyerMoore(searchArray2);
        var pLen = searchArray2.Length;
        var lst  = new Dictionary<string, int>();
        var tree = new List<byte[]>();
        if (pLen < endLength)
            throw new Exception("Search Pattern less than minimum search length.");
        var offset = 0;
        var wl     = startLength;
        do
        {
            var tpat = new byte[wl];
            Array.Copy(searchArray2, offset, tpat, 0, wl);
            tree.Add(tpat);
            bm.SetPattern(tpat);
            var idxl = bm.SearchAll(searchArray1);
            if (idxl.Item1.Count > 1)
            {
                var sapat = tpat.ToHexString();
                if (!lst.ContainsKey(sapat))
                    lst.Add(sapat, idxl.Item1.Count);
            }
            if (offset + wl >= pLen)
            {
                offset = 0;
                wl++;
                if (wl > endLength)
                    break;
                continue;
            }
            offset++;
        } while (wl != pLen + 1);
        return lst;
    }
}

BoyerMoore.cs

Posted on June 6, 2020  Leave a comment on BoyerMoore.cs

Boyer Moore Search Algorithm

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class BoyerMoore
{
    private int[]  _jumpTable;
    private byte[] _pattern;
    private int    _patternLength;
    public BoyerMoore()
    {
    }
    public BoyerMoore(byte[] pattern)
    {
        SetPattern(pattern);
    }
    public void SetPattern(byte[] pattern)
    {
        _pattern       = pattern;
        _jumpTable     = new int[256];
        _patternLength = _pattern.Length;
        for (var index = 0; index < 256; index++)
            _jumpTable[index] = _patternLength;
        for (var index = 0; index < _patternLength - 1; index++)
            _jumpTable[_pattern[index]] = _patternLength - index - 1;
    }
    public unsafe int Search(byte[] searchArray, int startIndex = 0)
    {
        if (_pattern == null)
            throw new Exception("Pattern has not been set.");
        if (_patternLength > searchArray.Length)
            throw new Exception("Search Pattern length exceeds search array length.");
        var index                 = startIndex;
        var limit                 = searchArray.Length - _patternLength;
        var patternLengthMinusOne = _patternLength     - 1;
        var Moves                 = 0;
        fixed (byte* pointerToByteArray = searchArray)
        {
            var pointerToByteArrayStartingIndex = pointerToByteArray + startIndex;
            fixed (byte* pointerToPattern = _pattern)
            {
                while (index <= limit)
                {
                    var j = patternLengthMinusOne;
                    while (j >= 0 && pointerToPattern[j] == pointerToByteArrayStartingIndex[index + j])
                        j--;
                    if (j < 0)
                        return index;
                    index += Math.Max(_jumpTable[pointerToByteArrayStartingIndex[index + j]] - _patternLength + 1 + j,
                        1);
                    Moves++;
                }
            }
        }
        return -1;
    }
    public unsafe (List<int>, int) SearchAll(byte[] searchArray, int startIndex = 0)
    {
        if (_pattern == null)
            throw new Exception("Pattern has not been set.");
        if (_patternLength > searchArray.Length)
            throw new Exception("Search Pattern length exceeds search array length.");
        var index                 = startIndex;
        var limit                 = searchArray.Length - _patternLength;
        var patternLengthMinusOne = _patternLength     - 1;
        var list                  = new List<int>();
        var Moves                 = 0;
        fixed (byte* pointerToByteArray = searchArray)
        {
            var pointerToByteArrayStartingIndex = pointerToByteArray + startIndex;
            fixed (byte* pointerToPattern = _pattern)
            {
                while (index <= limit)
                {
                    var j = patternLengthMinusOne;
                    while (j >= 0 && pointerToPattern[j] == pointerToByteArrayStartingIndex[index + j])
                        j--;
                    if (j < 0)
                        list.Add(index);
                    index += Math.Max(_jumpTable[pointerToByteArrayStartingIndex[index + j]] - _patternLength + 1 + j,
                        1);
                    Moves++;
                }
            }
        }
        return (list, Moves);
    }
    public int SuperSearch(byte[] searchArray, int nth, int start = 0)
    {
        var e = start;
        var c = 0;
        do
        {
            e = Search(searchArray, e);
            if (e == -1)
                return -1;
            c++;
            e++;
        } while (c < nth);
        return e - 1;
    }
    public static bool ContainsAny(byte[] sPattern, params byte[][] list)
    {
        return list.Select(v => new BoyerMoore(v)).Any(bm => bm.Search(sPattern) != -1);
    }
    public static bool ContainsAny(string sPattern, params string[] list)
    {
        return list.Select(s => new BoyerMoore(s.ToLower().GetBytes(Encoding.ASCII)))
            .Any(bm => bm.Search(sPattern.ToLower().GetBytes(Encoding.ASCII)) != -1);
    }
    }

MemoryBitmap.cs

Posted on June 6, 2020  Leave a comment on MemoryBitmap.cs

Direct Access Pixel Data, GetPixel, SetPixel

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
public unsafe class MemoryBitmap : IDisposable
{
    private readonly BitmapData _bmpData;
    private readonly int        _depth;
    private readonly byte*      _pfp;
    private readonly int        _stride;
    private          Bitmap     _memoryBitmap;
    public MemoryBitmap(string path)
    {
        if (path.IsNullOrEmpty())
            throw new Exception("Path cannot be null or empty.");
        if (!File.Exists(path))
            throw new Exception($"Path {path} does not exist.");
        var bitmap = new Bitmap(path);
        _memoryBitmap = bitmap;
        if (_memoryBitmap.PixelFormat != PixelFormat.Format32bppArgb && _memoryBitmap.PixelFormat != PixelFormat.Format24bppRgb && _memoryBitmap.PixelFormat != PixelFormat.Format8bppIndexed)
        {
            var clone = new Bitmap(_memoryBitmap.Width, _memoryBitmap.Height, PixelFormat.Format32bppArgb);
            using (var gr = Graphics.FromImage(clone))
            {
                gr.DrawImage(_memoryBitmap, new Rectangle(0, 0, clone.Width, clone.Height));
                _memoryBitmap = clone;
            }
        }
        Width  = _memoryBitmap.Width;
        Height = _memoryBitmap.Height;
        var rect = new Rectangle(0, 0, _memoryBitmap.Width, _memoryBitmap.Height);
        try
        {
            _bmpData = _memoryBitmap.LockBits(rect, ImageLockMode.ReadWrite, _memoryBitmap.PixelFormat);
        }
        catch (Exception ex)
        {
            throw new Exception("Could not lock bitmap", ex.InnerException);
        }
        _depth  = Image.GetPixelFormatSize(_bmpData.PixelFormat) / 8;
        _pfp    = (byte*) _bmpData.Scan0.ToPointer();
        _stride = _bmpData.Stride;
    }
    public MemoryBitmap(Bitmap bitmap)
    {
        _memoryBitmap = bitmap ?? throw new Exception("Bitmap cannot be null");
        if (_memoryBitmap.PixelFormat != PixelFormat.Format32bppArgb && _memoryBitmap.PixelFormat != PixelFormat.Format24bppRgb && _memoryBitmap.PixelFormat != PixelFormat.Format8bppIndexed)
        {
            var clone = new Bitmap(_memoryBitmap.Width, _memoryBitmap.Height, PixelFormat.Format32bppArgb);
            using (var gr = Graphics.FromImage(clone))
            {
                gr.DrawImage(_memoryBitmap, new Rectangle(0, 0, clone.Width, clone.Height));
                _memoryBitmap = clone;
            }
        }
        Width  = _memoryBitmap.Width;
        Height = _memoryBitmap.Height;
        var rect = new Rectangle(0, 0, _memoryBitmap.Width, _memoryBitmap.Height);
        try
        {
            _bmpData = _memoryBitmap.LockBits(rect, ImageLockMode.ReadWrite, _memoryBitmap.PixelFormat);
        }
        catch (Exception ex)
        {
            throw new Exception("Could not lock bitmap", ex.InnerException);
        }
        _depth  = Image.GetPixelFormatSize(_bmpData.PixelFormat) / 8;
        _pfp    = (byte*) _bmpData.Scan0.ToPointer();
        _stride = _bmpData.Stride;
    }
    public int Width
    {
        get;
    }
    public int Height
    {
        get;
    }
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    public void ConvertFormat(PixelFormat newPf)
    {
        var clone = new Bitmap(_memoryBitmap.Width, _memoryBitmap.Height, newPf);
        using (var gr = Graphics.FromImage(clone))
        {
            gr.DrawImage(_memoryBitmap, new Rectangle(0, 0, clone.Width, clone.Height));
            _memoryBitmap = clone;
        }
    }
    public void Save(string path)
    {
        _memoryBitmap.Save(path);
    }
    protected virtual void Dispose(bool disposing)
    {
        if (!disposing)
            return;
        if (_memoryBitmap != null)
            _memoryBitmap.UnlockBits(_bmpData);
    }
    private byte* PixelPointer(int x, int y)
    {
        return _pfp + y * _stride + x * _depth;
    }
    public Color GetPixel(int x, int y)
    {
        if (x < 0 || y < 0 || x >= Width || y >= Height)
            throw new Exception("Coordinates out of range");
        int a, r, g, b;
        var p = PixelPointer(x, y);
        if (_memoryBitmap.PixelFormat == PixelFormat.Format32bppArgb)
        {
            b = *p++;
            g = *p++;
            r = *p++;
            a = *p;
            return Color.FromArgb(a, r, g, b);
        }
        if (_memoryBitmap.PixelFormat == PixelFormat.Format24bppRgb)
        {
            b = *p++;
            g = *p++;
            r = *p;
            return Color.FromArgb(r, g, b);
        }
        if (_memoryBitmap.PixelFormat == PixelFormat.Format8bppIndexed)
        {
            a = *p;
            return Color.FromArgb(a, a, a);
        }
        return default;
    }
    public void SetPixel(int x, int y, Color col)
    {
        if (x < 0 || y < 0 || x >= Width || y >= Height)
            throw new Exception("Coordinates out of range");
        var p = PixelPointer(x, y);
        if (_memoryBitmap.PixelFormat == PixelFormat.Format32bppArgb)
        {
            *p++ = col.B;
            *p++ = col.G;
            *p++ = col.R;
            *p   = col.A;
            return;
        }
        if (_memoryBitmap.PixelFormat == PixelFormat.Format24bppRgb)
        {
            *p++ = col.B;
            *p++ = col.G;
            *p   = col.R;
            return;
        }
        if (_memoryBitmap.PixelFormat == PixelFormat.Format8bppIndexed)
            *p = col.B;
    }
}