BoyerMooreString.cs

BoyerMoore String Searching Algorithm

using System;
using System.Collections.Generic;
public class BoyerMooreString
{
    private       int[]  _jumpTable;
    private       string _pattern;
    private       int    _patternLength;
    public BoyerMooreString()
    {
    }
    public BoyerMooreString(string pattern)
    {
        SetPattern(pattern);
    }
    public void SetPattern(string pattern)
    {
        _pattern       = pattern;
        _jumpTable     = new int[ushort.MaxValue];
        _patternLength = _pattern.Length;
        for (var index = 0; index < ushort.MaxValue; ++index)
            _jumpTable[index] = _patternLength;
        for (var index = 0; index < _patternLength - 1; ++index)
            _jumpTable[_pattern[index]] = _patternLength - index - 1;
    }
    public unsafe int Search(string searray, int startIndex = 0)
    {
        if (_pattern == null)
            throw new Exception("Pattern has not been set.");
        if (_patternLength > searray.Length)
            throw new Exception("Search Pattern length exceeds search array length.");
        var num1 = startIndex;
        var num2 = searray.Length - _patternLength;
        var num3 = _patternLength - 1;
        var num4 = 0;
        fixed (char* chPtr1 = searray)
        {
            var chPtr2 = chPtr1 + startIndex;
            fixed (char* chPtr3 = _pattern)
            {
                while (num1 <= num2)
                {
                    var index = num3;
                    while (index >= 0 && chPtr3[index] == chPtr2[num1 + index])
                        --index;
                    if (index < 0)
                        return num1;
                    num1 += _jumpTable[chPtr2[num1 + index]];
                    ++num4;
                }
            }
        }
        return -1;
    }
    public unsafe (List<int>, int) SearchAll(string searray, int startIndex = 0)
    {
        if (_pattern == null)
            throw new Exception("Pattern has not been set.");
        if (_patternLength > searray.Length)
            throw new Exception("Search Pattern length exceeds search array length.");
        var num1    = startIndex;
        var num2    = searray.Length - _patternLength;
        var num3    = _patternLength - 1;
        var intList = new List<int>();
        var num4    = 0;
        fixed (char* chPtr1 = searray)
        {
            var chPtr2 = chPtr1 + startIndex;
            fixed (char* chPtr3 = _pattern)
            {
                while (num1 <= num2)
                {
                    var index = num3;
                    while (index >= 0 && chPtr3[index] == chPtr2[num1 + index])
                        --index;
                    if (index < 0)
                        intList.Add(num1);
                    num1 += _jumpTable[chPtr2[num1 + index]];
                    ++num4;
                }
            }
        }
        return (intList, num4);
    }
    public int SuperSearch(string searray, int nth, int start = 0)
    {
        var startIndex = start;
        var num1       = 0;
        do
        {
            var num2 = Search(searray, startIndex);
            if (num2 == -1)
                return -1;
            ++num1;
            startIndex = num2 + 1;
        } while (num1 < nth);
        return startIndex - 1;
    }
    public class BMPartialPatternSearchString
    {
        public int MinimumSearchLength;
        public BMPartialPatternSearchString(int min = 5)
        {
            MinimumSearchLength = min;
        }
        public (string partialPattern, int idx) SearchPartial(string pattern, string searray)
        {
            BoyerMooreString boyerMooreString = new BoyerMooreString(pattern);
            var              length           = pattern.Length;
            var              stringList       = new List<string>();
            if (length < MinimumSearchLength)
                throw new Exception("Search Pattern less than minimum search length.");
            var startIndex          = 0;
            var minimumSearchLength = MinimumSearchLength;
            do
            {
                var pattern1 = pattern.Substring(startIndex, minimumSearchLength);
                stringList.Add(pattern1);
                boyerMooreString.SetPattern(pattern1);
                int num = boyerMooreString.Search(searray);
                if (num != -1)
                    return (pattern1, num);
                if (startIndex + minimumSearchLength >= length)
                {
                    startIndex = 0;
                    ++minimumSearchLength;
                }
                else
                {
                    ++startIndex;
                }
            } while (minimumSearchLength != length + 1);
            return (pattern, -1);
        }
        public List<(string partialPattern, int idx)> SearchPartialFirst(
            string pattern,
            string searray)
        {
            BoyerMooreString boyerMooreString = new BoyerMooreString(pattern);
            var              length           = pattern.Length;
            var              valueTupleList   = new List<(string, int)>();
            var              stringList       = new List<string>();
            if (length < MinimumSearchLength)
                throw new Exception("Search Pattern less than minimum search length.");
            var startIndex          = 0;
            var minimumSearchLength = MinimumSearchLength;
            do
            {
                var pattern1 = pattern.Substring(startIndex, minimumSearchLength);
                stringList.Add(pattern1);
                boyerMooreString.SetPattern(pattern1);
                int num = boyerMooreString.Search(searray);
                if (num != -1)
                    valueTupleList.Add((pattern1, num));
                if (startIndex + minimumSearchLength >= length)
                {
                    startIndex = 0;
                    ++minimumSearchLength;
                }
                else
                {
                    ++startIndex;
                }
            } while (minimumSearchLength != length + 1);
            return new List<(string, int)>
                { (pattern, -1) };
        }
        public List<(string partialPattern, int idx)> SearchPartialAll(
            string pattern,
            string searray)
        {
            BoyerMooreString boyerMooreString = new BoyerMooreString(pattern);
            var              length           = pattern.Length;
            var              valueTupleList   = new List<(string, int)>();
            var              stringList       = new List<string>();
            if (length < MinimumSearchLength)
                throw new Exception("Search Pattern less than minimum search length.");
            var startIndex          = 0;
            var minimumSearchLength = MinimumSearchLength;
            do
            {
                var pattern1 = pattern.Substring(startIndex, minimumSearchLength);
                stringList.Add(pattern1);
                boyerMooreString.SetPattern(pattern1);
                (List<int>, int) tuple = boyerMooreString.SearchAll(searray);
                if (tuple.Item1.Count > 0)
                    foreach (var num in tuple.Item1)
                        valueTupleList.Add((pattern1, num));
                if (startIndex + minimumSearchLength >= length)
                {
                    startIndex = 0;
                    ++minimumSearchLength;
                }
                else
                {
                    ++startIndex;
                }
            } while (minimumSearchLength != length + 1);
            return valueTupleList;
        }
    }
}

EntropyEx.cs

Generic Entropy Class

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

SecureStringHelper.cs

Secure String Helper Class

public class SecureStringHelper : IDisposable
    {
        private readonly Encoding     _encoding;
        private readonly SecureString _secureString;
        private          byte[]       _bytes;
        private          bool         _disposed;
        public SecureStringHelper(SecureString secureString) : this(secureString, Encoding.Default)
        {
        }
        public SecureStringHelper(SecureString secureString, Encoding encoding)
        {
            if(secureString == null)
                throw new Exception(nameof(secureString));
            _encoding     = encoding ?? Encoding.Default;
            _secureString = secureString;
        }
        public void Dispose()
        {
            if(!_disposed)
            {
                Destroy();
                _disposed = true;
            }
            GC.SuppressFinalize(this);
        }
        public static string ToString(SecureString secureStr)
        {
            var Str = new NetworkCredential(string.Empty, secureStr).Password;
            return Str;
        }
        public static SecureString ToSecureString(string password)
        {
            if(password == null)
                throw new Exception("Error: Password cannot be null.");
            var securePassword = new SecureString();
            foreach(var c in password)
                securePassword.AppendChar(c);
            securePassword.MakeReadOnly();
            return securePassword;
        }
        internal unsafe byte[] ToByteArray()
        {
            if(_bytes != null)
            {
                _bytes.Fill(0);
                _bytes = null;
            }
            var maxLength = _encoding.GetMaxByteCount(_secureString.Length);
            var bytes     = IntPtr.Zero;
            var str       = IntPtr.Zero;
            try
            {
                bytes = Marshal.AllocHGlobal(maxLength);
                str   = Marshal.SecureStringToBSTR(_secureString);
                var chars = (char*) str.ToPointer();
                var bptr  = (byte*) bytes.ToPointer();
                var len   = _encoding.GetBytes(chars, _secureString.Length, bptr, maxLength);
                _bytes = new byte[len];
                for(var i = 0; i < len; ++i)
                {
                    _bytes[i] = *bptr;
                    bptr++;
                }
                return _bytes;
            }
            finally
            {
                if(bytes != IntPtr.Zero)
                    Marshal.FreeHGlobal(bytes);
                if(str != IntPtr.Zero)
                    Marshal.ZeroFreeBSTR(str);
            }
        }
        private void Destroy()
        {
            if(_bytes != null)
            {
                _bytes.Fill(0);
                _bytes = null;
            }
        }
    }

public static class SecureStringEx
    {
        /// <summary>
        ///     Converts a standard string to a secure string
        /// </summary>
        public static SecureString ToSecureString(this string password)
        {
            if(password == null)
                throw new Exception("Error: Password cannot be null.");
            var securePassword = new SecureString();
            foreach(var c in password)
                securePassword.AppendChar(c);
            securePassword.MakeReadOnly();
            return securePassword;
        }
    }

StringHelper.cs

String Helper Class

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Security;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
public static class StringHelper
{
    public static ushort[] SearchArray;
    /// <summary>
    ///     Included here as an example of field extraction through reflection.
    ///     Specific knowledge of the underlying class is needed. IE. _items in the list class.
    /// </summary>
    /// <param name="list"></param>
    /// <returns></returns>
    public static byte[] ExtractArray(this List<byte> list)
    {
        var t     = list.GetType();
        var items = t.GetField("_items", BindingFlags.NonPublic | BindingFlags.Instance);
        return items.GetValue(list) as byte[];
    }
    public static string Reverse(this string str)
    {
        var len                                  = str.Length;
        var Array                                = "";
        for (var i = len - 1; i >= 0; --i) Array += str[i];
        return Array;
    }
    public static string ToUTF16(this string str)
    {
        var AsciiBytes   = Encoding.ASCII.GetBytes(str);
        var unicodeBytes = Encoding.Convert(Encoding.ASCII, Encoding.Unicode, AsciiBytes);
        return Encoding.Unicode.GetString(unicodeBytes);
    }
    public static int CountInTheSet(this char c, string TheSet)
    {
        var Count = 0;
        if (TheSet        == null) return Count;
        if (TheSet.Length == 0) return Count;
        for (var j = 0; j < TheSet.Length; j++)
            if (c == TheSet[j])
                Count++;
        return Count;
    }
    public static bool EndsWith(this string s, char value)
    {
        var thisLen = s.Length;
        if (thisLen != 0)
            if (s[thisLen - 1] == value)
                return true;
        return false;
    }
    public static void SaveToFileComma(this Dictionary<string, string> d, string pathname)
    {
        using (var sw = new StreamWriter(pathname))
        {
            foreach (var e in d)
            {
                var k = e.Key + ",";
                var v = k     + e.Value;
                sw.WriteLine(v);
            }
        }
    }
    public static IDictionary<TKey, TValue> UpdateOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
    {
        if (dictionary.ContainsKey(key))
            dictionary[key] = value;
        else
            dictionary.Add(key, value);
        return dictionary;
    }
    public static void CopyToEx<T>(this List<T> obj, List<T> Target)
    {
        Target.AddRange(obj);
    }
    /// <summary>
    ///     tests if c is in the set TheSet
    /// </summary>
    /// <param name="c"></param>
    /// <param name="TheSet"></param>
    /// <returns></returns>
    public static bool InTheSet(this char c, string TheSet)
    {
        if (TheSet        == null) return false;
        if (TheSet.Length == 0) return false;
        return TheSet.Any(T => c == T);
    }
    public static string Join(this string separator, IEnumerable<string> values)
    {
        using (var enumerator = values.GetEnumerator())
        {
            if (!enumerator.MoveNext())
                return string.Empty;
            var res = enumerator.Current;
            while (enumerator.MoveNext())
            {
                res += separator;
                res += enumerator.Current;
            }
            return res;
        }
    }
    [SecuritySafeCritical]
    [__DynamicallyInvokable]
    private static unsafe List<int> IndexesOf(this string Haystack, string Needle)
    {
        var Indexes = new List<int>();
        var nh      = Encoding.Default.GetBytes(Haystack);
        var nn      = Encoding.Default.GetBytes(Needle);
        fixed (byte* H = nh)
        {
            fixed (byte* N = nn)
            {
                var i = 0;
                for (byte* hNext = H, hEnd = H + nh.Length; hNext < hEnd; i++, hNext++)
                {
                    var Found = true;
                    for (byte* hInc = hNext, nInc = N, nEnd = N + nn.Length; Found && nInc < nEnd; Found = *nInc == *hInc, nInc++, hInc++)
                        ;
                    if (Found)
                        Indexes.Add(i);
                }
                return Indexes;
            }
        }
    }
    /// <summary>
    ///     Convert a string into a byte array of type ascii
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static byte[] StrToByteArray(this string str)
    {
        if (str == null)
            return null;
        if (str.Length == 0)
            return null;
        return Encoding.ASCII.GetBytes(str);
    }
    public static char CharAt(this string str, int Index)
    {
        return str.Substring(Index, 1).ToCharArray()[0];
    }
    /// <summary>
    ///     Takes a delimited string and converts it into a generic object Example: 1,2,3,4 in string form = 1234 in array form
    /// </summary>
    /// <param name="input"></param>
    /// <param name="separator"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    public static object[] StringToArray(this string input, string separator, Type type)
    {
        var stringList = input.Split(separator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
        var list       = new object[stringList.Length];
        for (var i = 0; i < stringList.Length; i++)
            list[i] = Convert.ChangeType(stringList[i], type);
        return list;
    }
    public static byte[] HexToByte(this string hex)
    {
        if (hex.Length % 2 == 1)
            throw new Exception("The binary key cannot have an odd number of digits");
        var len = hex.Length >> 1;
        var arr = new byte[len];
        for (var i = 0; i < len; ++i)
            arr[i] = (byte) ((GetHexVal(hex[i << 1]) << 4) + GetHexVal(hex[(i << 1) + 1]));
        return arr;
    }
    private static int GetHexVal(char hex)
    {
        int val = hex;
        return val - (val < 58 ? 48 : val < 97 ? 55 : 87);
    }
    /// <summary>
    ///     takes a composite string like "12,13,14,15,16' and creates a string array
    /// </summary>
    /// <param name="input"></param>
    /// <param name="separator"></param>
    /// <returns></returns>
    public static string[] StringToStringArray(this string input, string separator)
    {
        var stringList = input.Split(separator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
        return stringList;
    }
    /// <summary>
    ///     tests to find out if s contains all strings in TopList
    /// </summary>
    /// <param name="s"></param>
    /// <param name="TopList"></param>
    /// <returns></returns>
    public static bool ContainsAll(this string s, List<string> sl)
    {
        var sx  = s.ToLower();
        var sl1 = new List<string>();
        var a   = 0;
        foreach (var tls in sl)
            sl1.Add(tls.ToLower());
        var Count = 0;
        foreach (var ts in sl1)
            if (sx.IndexOf(ts, StringComparison.OrdinalIgnoreCase) != -1)
                Count++;
        if (Count > 4)
            a = Count;
        if (Count >= 4)
            return true;
        return false;
    }
    public static bool IsPrint(this string s)
    {
        var c = (byte) s[0];
        if (c >= 0x20 && c <= 0x7f || c == 0x0A || c == 0x0D)
            return true;
        return false;
    }
    public static bool IsPrint(this char c)
    {
        if (c >= 0x20 && c <= 0x7f || c == 0x0A || c == 0x0D)
            return true;
        return false;
    }
    public static bool IsLetter(this char c)
    {
        if (c >= 65 && c <= 90 || c >= 97 && c <= 122)
            return true;
        return false;
    }
    public static bool IsAlphaNumeric(this string s)
    {
        return s.IsLetter() || s.IsDigit();
    }
    public static bool IsAlphaNumeric(this char c)
    {
        return c.IsLetter() || c.IsDigit();
    }
    public static bool IsLetter(this string s)
    {
        var c = (byte) s[0];
        if (c >= 65 && c <= 90 || c >= 97 && c <= 122)
            return true;
        return false;
    }
    public static bool IsOnlyAlpha(this string s)
    {
        var c = 0;
        for (var i = 0; i < s.Length; i++)
            if (IsAlpha(s))
                c++;
        if (c == s.Length)
            return true;
        return false;
    }
    /// <summary>
    ///     A better IsAlpha which includes CR and LF as well as all characters between 0x20 and 0x7f
    /// </summary>
    /// <param name="c"></param>
    /// <returns></returns>
    public static bool IsAlpha(this string c)
    {
        var Count = 0;
        for (var i = 0; i < c.Length; i++)
            if (IsPrint(c.Substring(0, 1)))
                Count++;
        if (Count == c.Length)
            return true;
        return false;
    }
    /// <summary>
    ///     Indicates whether the specified string is null or is an empty string.
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static bool IsNullOrEmpty(this string s)
    {
        return string.IsNullOrEmpty(s);
    }
    public static bool IsAlpha(this char c)
    {
        return IsPrint(c);
    }
    public static bool IsLowwer(this string c)
    {
        return c.InTheSet("abcdefghijklmnopqrstuvwxyz");
    }
    public static bool IsLowwer(this char c)
    {
        return c.InTheSet("abcdefghijklmnopqrstuvwxyz");
    }
    public static bool IsVowel(this string c)
    {
        return InTheSet(c.ToLower(), "AEIOU".ToLower());
    }
    public static bool IsConsonant(this string c)
    {
        return InTheSet(c.ToLower(), "BCDFGHJKLMNPQRSTVWXYZ".ToLower());
    }
    public static bool IsVowel(this char c)
    {
        return "AEIOUaeiou".IndexOf(c) != -1;
    }
    public static bool IsConsonant(this char c)
    {
        return "BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz".IndexOf(c) != -1;
    }
    public static int ContainsDigitAt(this string str)
    {
        for (var i = 0; i < str.Length; i++)
            if (IsDigit(str[i].ToString()))
                return i;
        return -1;
    }
    public static bool IsFloat(this string str)
    {
        return str.Any(T => T == '.');
    }
    public static bool IsDigit(this string c)
    {
        if (c.Length > 1)
            return c.InTheSet("0123456789.");
        return c.InTheSet("0123456789");
    }
    public static bool IsDigit(this char c)
    {
        return c.InTheSet("0123456789");
    }
    public static bool IsSpecialCharacter(this string c)
    {
        return InTheSet(c, "~`!@#$%^&*()_+-={}[]|:;'<>?,./");
    }
    public static bool IsSpecialCharacter(this char c)
    {
        return InTheSet(c, "~`!@#$%^&*()_+-={}[]|:;'<>?,./");
    }
    /// <summary>
    ///     Test c to see if it contains any special characters
    /// </summary>
    /// <param name="c"></param>
    /// <returns></returns>
    public static bool ContainsSpecialCharacter(this string c)
    {
        var TheSet = "~`!@#$%^&*()_+-={}[]|:;'<>?,./";
        for (var j = 0; j < TheSet.Length; j++)
        for (var k = 0; k < c.Length; k++)
            if (c[k] == TheSet[j])
                return true;
        return false;
    }
    /// <summary>
    ///     Check to see if this character is contained within the set
    /// </summary>
    /// <param name="c">The c.</param>
    /// <param name="TheSet">The set.</param>
    /// <returns></returns>
    public static bool InTheSet(this string c, string TheSet)
    {
        var result = false;
        if (TheSet == null)
            return result;
        if (TheSet.Length == 0)
            return result;
        if (c == null)
            return result;
        if (c.Length == 0)
            return result;
        for (var j = 0; j < TheSet.Length; j++)
            if (c[0] == TheSet[j])
            {
                result = true;
                break;
            }
        return result;
    }
    /// <summary>
    ///     Check to see if this character is contained within the set
    /// </summary>
    /// <param name="c">The c.</param>
    /// <param name="TheSet">The set.</param>
    /// <returns></returns>
    public static bool InTheSet(this char c, char[] TheSet)
    {
        var result = false;
        if (TheSet == null)
            return result;
        if (TheSet.Length == 0)
            return result;
        for (var j = 0; j < TheSet.Length; j++)
            if (c == TheSet[j])
            {
                result = true;
                break;
            }
        return result;
    }
    public static int IndexOfN(this string str, string pattern, int n)
    {
        var c  = 0;
        var f  = pattern[0];
        var pl = pattern.Length;
        var e  = str.IndexOf(f);
        if (e == -1)
            return -1;
        do
        {
            try
            {
                e = str.IndexOf(pattern, e, StringComparison.OrdinalIgnoreCase);
            }
            catch
            {
                return -1;
            }
            if (e == -1)
                return -1;
            c++;
            e = str.IndexOf(f, e + pl + 1);
            if (e == -1)
                return -1;
        } while (c < n);
        return e - 1;
    }
    /// <summary>
    ///     Gets all indices of the pattern within the string
    /// </summary>
    /// <param name="str">The string.</param>
    /// <param name="pattern">The pattern.</param>
    /// <returns></returns>
    public static List<int> GetAllIndices(this string str, string pattern)
    {
        var lst = new List<int>();
        var f   = pattern[0];
        var pl  = pattern.Length;
        var e   = 0;
        var p   = str.IndexOf(f);
        do
        {
            try
            {
                e = str.IndexOf(pattern, p, StringComparison.OrdinalIgnoreCase);
            }
            catch
            {
                return lst;
            }
            if (e != -1)
            {
                lst.Add(e);
                p = str.IndexOf(f, e + pl);
                if (p == -1)
                    break;
            }
            else
            {
                break;
            }
        } while (e != -1);
        return lst;
    }
    public static int GetCharacterCount(this string p)
    {
        var map = new Dictionary<char, int>();
        foreach (var c in p)
            if (!map.ContainsKey(c))
                map.Add(c, 1);
            else
                map[c] += 1;
        return map.Count;
    }
    public static Dictionary<char, int> CountCharacter(this string p)
    {
        var map = new Dictionary<char, int>();
        foreach (var c in p)
            if (!map.ContainsKey(c))
                map.Add(c, 1);
            else
                map[c] += 1;
        return map;
    }
    public static int CharacterCount(this string p, char c0)
    {
        var count = 0;
        foreach (var c in p)
            if (c.Equals(c0))
                count++;
        return count;
    }
    public static bool MajorCharacter(this string p, char c)
    {
        var cc = p.CountCharacter();
        var hc = '\0';
        var mv = 0;
        foreach (var v in cc)
            if (v.Value > mv)
            {
                mv = v.Value;
                hc = v.Key;
            }
        return hc == c;
    }
    /// <summary>
    ///     Test to see if p contains only characters contained in s
    /// </summary>
    public static bool ContainsOnly(this string p, string s)
    {
        return p.Count(c => s.Any(c1 => c == c1)) == p.Length;
    }
    public static bool ContainsOnlyTheseCharacters(this string p, params char[] c)
    {
        var cc = p.CountCharacter();
        if (cc.Count > c.Length)
            return false;
        var pac = p.ToCharArray();
        var u   = pac.Except(c).ToArray();
        if (u.Length == 0)
            return true;
        return false;
    }
    public static double Uniqueness(this string s, double CharactersAllowed)
    {
        var map = new Dictionary<char, int>();
        foreach (var c in s)
            if (!map.ContainsKey(c))
                map.Add(c, 1);
            else
                map[c] += 1;
        return map.Count / CharactersAllowed * 100D;
    }
    /// <summary>
    ///     find the nth occurrence of substr within str return the index (For reverse compatibility)
    /// </summary>
    /// <param name="str"></param>
    /// <param name="substr"></param>
    /// <param name="nth"></param>
    /// <returns></returns>
    public static int SuperIndexOf(this string str, string substr, int nth)
    {
        var e = 0;
        var c = 0;
        var l = str.Length;
        do
        {
            e = str.IndexOf(substr, e, StringComparison.CurrentCultureIgnoreCase);
            if (e == -1)
                return -1;
            c++;
            e++;
            if (e >= l)
                return -1;
        } while (c < nth);
        return e - 1;
    }
    /// <summary>
    ///     find the nth occurrence of substr within str return the index (IgnoreCase)
    /// </summary>
    public static int IndexNOf(this string str, string substr, int nth)
    {
        if (str == null || substr == null || nth < 0)
            return -1;
        var e = 0;
        var c = 0;
        var l = str.Length;
        do
        {
            e = str.IndexOf(substr, e, StringComparison.CurrentCultureIgnoreCase);
            if (e == -1)
                return -1;
            c++;
            e++;
            if (e >= l)
                return -1;
        } while (c < nth);
        return e - 1;
    }
    public static List<string> StringToList(this string input, string separator)
    {
        return input.Split(separator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
    }
    /// <summary>
    ///     Returns a <see cref="System.String" /> that represents this instance with commas.
    /// </summary>
    /// <param name="s">The s.</param>
    /// <returns>
    ///     A <see cref="System.String" /> that represents this instance.
    /// </returns>
    public static string ToStringWithCommas(this int s)
    {
        return s.ToString("N0");
    }
    public static string InsertCommas(this string str)
    {
        if (str == null)
            return "";
        var pos  = str.IndexOf('.');
        var frac = "";
        if (pos != -1)
        {
            frac = str.Substring(pos);
            str  = str.Substring(0, pos);
        }
        var rs  = str;
        var len = str.Length;
        if (len > 3)
            for (int i = 0, j = 0; i < len; i++)
                if (i != 0)
                    if ((len - i) % 3 == 0)
                    {
                        rs = rs.Insert(i + j, ",");
                        j++;
                    }
        return rs + frac;
    }
    public static byte[] ToByteArrayDefault(this string str)
    {
        return Encoding.Default.GetBytes(str);
    }
    public static byte[] FromBase64(this string str)
    {
        return Convert.FromBase64String(str);
    }
    public static string B64Encode(this string S)
    {
        if (S == null)
            return "";
        var encbuff = Encoding.Default.GetBytes(S);
        var enc     = Convert.ToBase64String(encbuff);
        return enc;
    }
    public static int WordCount(this string s)
    {
        var Count = 0;
        foreach (var sc in s)
            if (sc == ' ')
                Count++;
        return Count + 1;
    }
    /// <summary>
    ///     Allocate and zero the search array
    /// </summary>
    /// <param name="s"></param>
    public static void NewSearchArray(this string s)
    {
        SearchArray = new ushort[s.Length];
    }
    /// <summary>
    ///     Get the search array for external use
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static ushort[] GetSearchArray(this string s)
    {
        return SearchArray;
    }
    public static bool IsEven(this short o)
    {
        if ((ulong) o % 2 == 0)
            return true;
        return false;
    }
    public static bool IsEven(this ushort o)
    {
        if ((ulong) o % 2 == 0)
            return true;
        return false;
    }
    public static bool IsEven(this uint o)
    {
        if ((ulong) o % 2 == 0)
            return true;
        return false;
    }
    public static bool IsEven(this ulong o)
    {
        if (o % 2 == 0)
            return true;
        return false;
    }
    public static string RemoveDiacritics(this string s)
    {
        var stFormD = s.Normalize(NormalizationForm.FormD);
        var sb      = new StringBuilder();
        for (var i = 0; i < stFormD.Length; i++)
        {
            var uc = CharUnicodeInfo.GetUnicodeCategory(stFormD[i]);
            if (uc != UnicodeCategory.NonSpacingMark)
                sb.Append(stFormD[i]);
        }
        return sb.ToString().Normalize(NormalizationForm.FormC);
    }
    public static string RemoveSpaces(this string s)
    {
        return s.Replace(" ", "");
    }
    public static bool IsNumber(this string s, bool floatpoint)
    {
        int    i;
        double d;
        var    withoutWhiteSpace = s.RemoveSpaces();
        if (floatpoint)
            return double.TryParse(withoutWhiteSpace, NumberStyles.Any, Thread.CurrentThread.CurrentUICulture, out d);
        return int.TryParse(withoutWhiteSpace, out i);
    }
    public static string UppercaseFirstLetter(this string value)
    {
        if (value.Length > 0)
        {
            var array = value.ToCharArray();
            array[0] = char.ToUpper(array[0]);
            return new string(array);
        }
        return value;
    }
    public static string ToInitials(this string str)
    {
        return Regex.Replace(str, @"^(?'b'\w)\w*,\s*(?'a'\w)\w*$|^(?'a'\w)\w*\s*(?'b'\w)\w*$", "${a}${b}", RegexOptions.Singleline);
    }
    public static string RemoveLineBreaks(this string lines)
    {
        return lines.Replace("\r", "").Replace("\n", "");
    }
    public static string ReplaceLineBreaks(this string lines, string replacement)
    {
        return lines.Replace("\r\n", replacement).Replace("\r", replacement).Replace("\n", replacement);
    }
    public static string StripHtml(this string html)
    {
        if (string.IsNullOrEmpty(html))
            return string.Empty;
        return Regex.Replace(html, @"<[^>]*>", " ");
    }
    public static string StripHTML(this string source)
    {
        try
        {
            string result;
            result = source.Replace("\r", " ");
            result = result.Replace("\n", " ");
            result = result.Replace("\t", string.Empty);
            result = Regex.Replace(result, @"( )+",                      " ");
            result = Regex.Replace(result, @"<( )*head([^>])*>",         "<head>",     RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<( )*(/)( )*head( )*>)",   "</head>",    RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(<head>).*?(</head>)",       string.Empty, RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*script([^>])*>",       "<script>",   RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<( )*(/)( )*script( )*>)", "</script>",  RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<script>).*?(</script>)",  string.Empty, RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*style([^>])*>",        "<style>",    RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<( )*(/)( )*style( )*>)",  "</style>",   RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(<style>).*?(</style>)",     string.Empty, RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*td([^>])*>",           "\t",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*br( )*(/)?( )*>",      "\r",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*li( )*>",              "\r",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*div([^>])*>",          "\r\r",       RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*tr([^>])*>",           "\r\r",       RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*p([^>])*>",            "\r\r",       RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<[^>]*>",                   string.Empty, RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @" ",                         " ",          RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"•",                    " * ",        RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"‹",                  "<",          RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"›",                  ">",          RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"™",                   "(tm)",       RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"⁄",                   "/",          RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<",                      "<",          RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @">",                      ">",          RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"©",                    "(c)",        RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"®",                     "(r)",        RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"&(.{2,6});",                string.Empty, RegexOptions.IgnoreCase);
            result = result.Replace("\n", "\r");
            result = Regex.Replace(result, "(\r)( )+(\r)",  "\r\r", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\t)( )+(\t)",  "\t\t", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\t)( )+(\r)",  "\t\r", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\r)( )+(\t)",  "\r\t", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\r)(\t)+(\r)", "\r\r", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\r)(\t)+",     "\r\t", RegexOptions.IgnoreCase);
            var breaks = "\r\r\r";
            var tabs   = "\t\t\t\t\t";
            for (var index = 0; index < result.Length; index++)
            {
                result = result.Replace(breaks, "\r\r");
                result = result.Replace(tabs,   "\t\t\t\t");
                breaks = breaks + "\r";
                tabs   = tabs   + "\t";
            }
            return result;
        }
        catch
        {
            return source;
        }
    }
    public static string StripHTMLNE(this string source)
    {
        try
        {
            string result;
            result = source.Replace("\r", " ");
            result = result.Replace("\n", " ");
            result = result.Replace("\t", " ");
            result = Regex.Replace(result, @"( )+",                      " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*head([^>])*>",         "<head>",    RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<( )*(/)( )*head( )*>)",   "</head>",   RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(<head>).*?(</head>)",       " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*script([^>])*>",       "<script>",  RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<( )*(/)( )*script( )*>)", "</script>", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<script>).*?(</script>)",  " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*style([^>])*>",        "<style>",   RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<( )*(/)( )*style( )*>)",  "</style>",  RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(<style>).*?(</style>)",     " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*td([^>])*>",           "\t",        RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*br( )*(/)?( )*>",      "\r",        RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*li( )*>",              "\r",        RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*div([^>])*>",          "\r\r",      RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*tr([^>])*>",           "\r\r",      RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*p([^>])*>",            "\r\r",      RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<[^>]*>",                   " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @" ",                         " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"&nbsp",                     " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"•",                    " * ",       RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"‹",                  "<",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"›",                  ">",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"™",                   "(tm)",      RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"⁄",                   "/",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<",                      "<",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @">",                      ">",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"©",                    "(c)",       RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"®",                     "(r)",       RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"&(.{2,6});",                " ",         RegexOptions.IgnoreCase);
            result = result.Replace("\n", "\r");
            result = Regex.Replace(result, "(\r)( )+(\r)",  "\r\r", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\t)( )+(\t)",  "\t\t", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\t)( )+(\r)",  "\t\r", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\r)( )+(\t)",  "\r\t", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\r)(\t)+(\r)", "\r\r", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\r)(\t)+",     "\r\t", RegexOptions.IgnoreCase);
            var breaks = "\r\r\r";
            var tabs   = "\t\t\t\t\t";
            for (var index = 0; index < result.Length; index++)
            {
                result = result.Replace(breaks, "\r\r");
                result = result.Replace(tabs,   "\t\t\t\t");
                breaks = breaks + "\r";
                tabs   = tabs   + "\t";
            }
            return result;
        }
        catch
        {
            return source;
        }
    }
    public static string StripHTMLAll(this string source)
    {
        try
        {
            string result;
            result = source.Replace("\r", " ");
            result = result.Replace("\n", " ");
            result = result.Replace("\t", " ");
            result = Regex.Replace(result, @"( )+",                      " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*head([^>])*>",         "<head>",    RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<( )*(/)( )*head( )*>)",   "</head>",   RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(<head>).*?(</head>)",       " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*script([^>])*>",       "<script>",  RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<( )*(/)( )*script( )*>)", "</script>", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<script>).*?(</script>)",  " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*style([^>])*>",        "<style>",   RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"(<( )*(/)( )*style( )*>)",  "</style>",  RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(<style>).*?(</style>)",     " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*td([^>])*>",           "\t",        RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*br( )*(/)?( )*>",      "\r",        RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*li( )*>",              "\r",        RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*div([^>])*>",          "\r\r",      RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*tr([^>])*>",           "\r\r",      RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<( )*p([^>])*>",            "\r\r",      RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<[^>]*>",                   " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @" ",                         " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"&nbsp",                     " ",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"•",                    " * ",       RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"‹",                  "<",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"›",                  ">",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"™",                   "(tm)",      RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"⁄",                   "/",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"<",                      "<",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @">",                      ">",         RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"©",                    "(c)",       RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"®",                     "(r)",       RegexOptions.IgnoreCase);
            result = Regex.Replace(result, @"&(.{2,6});",                " ",         RegexOptions.IgnoreCase);
            result = result.Replace("\n", " ");
            result = result.Replace("\r", " ");
            result = result.Replace("\t", " ");
            result = result.Replace("\n", "\r");
            result = Regex.Replace(result, "(\r)( )+(\r)",  "\r\r", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\t)( )+(\t)",  "\t\t", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\t)( )+(\r)",  "\t\r", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\r)( )+(\t)",  "\r\t", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\r)(\t)+(\r)", "\r\r", RegexOptions.IgnoreCase);
            result = Regex.Replace(result, "(\r)(\t)+",     "\r\t", RegexOptions.IgnoreCase);
            var breaks = "\r\r\r";
            var tabs   = "\t\t\t\t\t";
            for (var index = 0; index < result.Length; index++)
            {
                result = result.Replace(breaks, "\r\r");
                result = result.Replace(tabs,   "\t\t\t\t");
                breaks = breaks + "\r";
                tabs   = tabs   + "\t";
            }
            return result;
        }
        catch
        {
            return source;
        }
    }
    /// <summary>
    ///     If the searchstring contains any occurrences of the list values returns true else false.
    /// </summary>
    public static bool ContainsAny(this string searchstring, params string[] list)
    {
        var sslcs = searchstring.ToLower();
        var bfss  = sslcs.GetBytes(Encoding.ASCII);
        foreach (var s in list)
        {
            var lcs = s.ToLower();
            var bf  = lcs.GetBytes(Encoding.ASCII);
            var bm  = new BoyerMoore(bf);
            if (bm.Search(bfss) != -1)
                return true;
        }
        return false;
    }
    public static string DownloadURLToString(this string url)
    {
        var webReq = (HttpWebRequest) WebRequest.Create(url);
        try
        {
            webReq.CookieContainer = new CookieContainer();
            webReq.Method          = "GET";
            webReq.UserAgent       = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36";
            using (var response = webReq.GetResponse())
            {
                using (var stream = response.GetResponseStream())
                {
                    var reader = new StreamReader(stream);
                    return reader.ReadToEnd();
                }
            }
        }
        catch (Exception ex)
        {
        }
        return "";
    }
    public static string ReverseWords(this string str, char sep)
    {
        char temp;
        int  left  = 0, middle = 0;
        var  chars = str.ToCharArray();
        Array.Reverse(chars);
        for (var i = 0; i <= chars.Length; i++)
        {
            if (i != chars.Length && chars[i] != sep)
                continue;
            if (left == i || left + 1 == i)
            {
                left = i + 1;
                continue;
            }
            middle = (i - left - 1) / 2 + left;
            for (var j = i - 1; j > middle; j--, left++)
            {
                temp        = chars[left];
                chars[left] = chars[j];
                chars[j]    = temp;
            }
            left = i + 1;
        }
        return new string(chars);
    }
    public static string ReverseWords(this string str)
    {
        return str.ReverseWords(' ');
    }
}