BigIntegerHelper.cs

BigInteger Helper Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
public static class BigIntegerHelper
{
    private static readonly BigInteger Ten   = new BigInteger(10);
    private static readonly BigInteger Three = new BigInteger(3);
    private static readonly BigInteger ONE   = new BigInteger(1);
    private static readonly BigInteger Two   = new BigInteger(2);
    public static BigInteger BigIntegerBase2(this string binaryValue)
    {
        BigInteger res = 0;
        if (binaryValue.Count(b => b == '1') + binaryValue.Count(b => b == '0') != binaryValue.Length) return res;
        foreach (var c in binaryValue)
        {
            res <<= 1;
            res +=  c == '1' ? 1 : 0;
        }
        return res;
    }
    public static BigInteger BigIntegerBase16(this string hexNumber)
    {
        if (string.IsNullOrEmpty(hexNumber))
            throw new Exception("Error: hexNumber cannot be either null or have a length of zero.");
        if (!hexNumber.ContainsOnly("0123456789abcdefABCDEFxX"))
            throw new Exception("Error: hexNumber cannot contain characters other than 0-9,a-f,A-F, or xX");
        hexNumber = hexNumber.ToUpper();
        if (hexNumber.IndexOf("0X", StringComparison.OrdinalIgnoreCase) != -1)
            hexNumber = hexNumber.Substring(2);
        var bytes = Enumerable.Range(0, hexNumber.Length)
            .Where(x => x % 2 == 0)
            .Select(x => Convert.ToByte(hexNumber.Substring(x, 2), 16))
            .ToArray();
        return new BigInteger(bytes.Concat(new byte[] {0}).ToArray());
    }
    public static BigInteger BigIntegerBase10(this string str)
    {
        var number = new BigInteger();
        int i;
        for (i = 0; i < str.Length; i++)
            if (str[i] >= '0' && str[i] <= '9')
                number = number * Ten + long.Parse(str[i].ToString());
        return number;
    }
    private static byte[] HexToByteArray(this string hex)
    {
        return Enumerable.Range(0, hex.Length)
            .Where(x => x % 2 == 0)
            .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
            .ToArray();
    }
    public static BigInteger ToBigInteger(this char ul)
    {
        return new BigInteger(ul);
    }
    public static BigInteger ToBigInteger(this byte ul)
    {
        return new BigInteger(ul);
    }
    public static BigInteger ToBigInteger(this sbyte ul)
    {
        return new BigInteger(ul);
    }
    public static BigInteger ToBigInteger(this short ul)
    {
        return new BigInteger(ul);
    }
    public static BigInteger ToBigInteger(this ushort ul)
    {
        return new BigInteger(ul);
    }
    public static BigInteger ToBigInteger(this int ul)
    {
        return new BigInteger((ulong) ul);
    }
    public static BigInteger ToBigInteger(this uint ul)
    {
        return new BigInteger((ulong) ul);
    }
    public static BigInteger ToBigInteger(this long ul)
    {
        return new BigInteger((ulong) ul);
    }
    public static BigInteger ToBigInteger(this ulong ul)
    {
        return new BigInteger(ul);
    }
    public static BigInteger ModPow(this BigInteger n, BigInteger e, BigInteger m)
    {
        var s = ONE;
        var u = e;
        while (!u.IsZero)
        {
            if ((u & ONE) == 1)
                s = s * n % m;
            u >>= 1;
            n =   n * n % m;
        }
        return s;
    }
    public static double ConfidenceToProbability(int confidence)
    {
        var a = Two.Pow(confidence);
        var b = 100.0 / (double) a;
        var c = 100.0 - b;
        return c;
    }
    public static BigInteger Pow(this BigInteger n, BigInteger exp)
    {
        var y = ONE;
        var z = n;
        while (exp != 0)
        {
            if ((exp & 0x1) == 1)
                y *= z;
            exp >>= 1;
            if (exp != 0)
                z *= z;
        }
        return y;
    }
    public static List<BigInteger> GetFactors(this BigInteger n)
    {
        var Factors = new List<BigInteger>();
        var s       = n.Sqrt();
        var a       = Three;
        while (a < s)
        {
            if (n % a == 0)
            {
                Factors.Add(a);
                if (a * a != n)
                    Factors.Add(n / a);
            }
            a += 2;
        }
        return Factors;
    }
    public static BigInteger Gcd(this BigInteger a, BigInteger b)
    {
        while (b > BigInteger.Zero)
        {
            var r = a % b;
            a = b;
            b = r;
        }
        return a;
    }
    public static BigInteger Lcm(this BigInteger a, BigInteger b)
    {
        return a * b / a.Gcd(b);
    }
    public static BigInteger BigIntegerBase2(this BigInteger bi, string binaryValue)
    {
        bi = BigInteger.Zero;
        if (binaryValue.Count(b => b == '1') + binaryValue.Count(b => b == '0') != binaryValue.Length)
            return bi;
        foreach (var c in binaryValue)
        {
            bi <<= 1;
            bi +=  c == '1' ? 1 : 0;
        }
        return bi;
    }
    public static int GetByteWidth(this BigInteger n)
    {
        return GetBitWidth(n) >> 3;
    }
    public static int GetBitWidth(this BigInteger n)
    {
        BigInteger bitWidth = 1;
        var        v        = n;
        while ((v >>= 1) > 0)
            bitWidth++;
        if (bitWidth < 8)
            bitWidth = 8;
        return (int) bitWidth;
    }
    public static BigInteger GetMaxValue(this BigInteger bi, int bitLength)
    {
        if (bi.Sign == -1)
            bitLength -= 1;
        return BigInteger.One << bitLength;
    }
    public static BigInteger GetMaxValue(this BigInteger bi)
    {
        var bitLength = bi.GetBitWidth();
        if (bi.Sign == -1)
            bitLength -= 1;
        return (BigInteger.One << bitLength) - BigInteger.One;
    }
    public static BigInteger GetMaxValueBitWidth(int bitLength)
    {
        return (BigInteger.One << bitLength) - BigInteger.One;
    }
    public static BigInteger BigIntegerBase16(this BigInteger bi, string hexNumber)
    {
        if (string.IsNullOrEmpty(hexNumber))
            throw new Exception("Error: hexNumber cannot be either null or have a length of zero.");
        if (!hexNumber.ContainsOnly("0123456789abcdefABCDEFxX"))
            throw new Exception("Error: hexNumber cannot contain characters other than 0-9,a-f,A-F, or xX");
        hexNumber = hexNumber.ToUpper();
        if (hexNumber.IndexOf("0X", StringComparison.OrdinalIgnoreCase) != -1)
            hexNumber = hexNumber.Substring(2);
        var bytes = Enumerable.Range(0, hexNumber.Length)
            .Where(x => x % 2 == 0)
            .Select(x => Convert.ToByte(hexNumber.Substring(x, 2), 16))
            .ToArray();
        return new BigInteger(bytes.Concat(new byte[] {0}).ToArray());
    }
    public static BigInteger BigIntegerBase10(this BigInteger bi, string str)
    {
        if (str[0] == '-' || str.IndexOf('.') != -1)
            throw new Exception($"Invalid numeric string. Only positive numbers and whole numbers are allowed. Value={str}");
        var number = new BigInteger();
        int i;
        for (i = 0; i < str.Length; i++)
            if (str[i] >= '0' && str[i] <= '9')
                number = number * Ten + long.Parse(str[i].ToString());
        return number;
    }
    public static string ToBinaryString(this BigInteger bigint)
    {
        var bytes  = bigint.ToByteArray();
        var index  = bytes.Length - 1;
        var base2  = new StringBuilder(bytes.Length * 8);
        var binary = Convert.ToString(bytes[index], 2);
        if (binary[0] != '0' && bigint.Sign == 1) base2.Append('0');
        base2.Append(binary);
        for (index--; index >= 0; index--)
            base2.Append(Convert.ToString(bytes[index], 2).PadLeft(8, '0'));
        return base2.ToString();
    }
    public static string ToHexString(this BigInteger bi)
    {
        var bytes = bi.ToByteArray();
        var sb    = new StringBuilder();
        foreach (var b in bytes)
        {
            var hex = b.ToString("X2");
            sb.Append(hex);
        }
        return sb.ToString();
    }
    public static string ToOctalString(this BigInteger bigint)
    {
        var bytes         = bigint.ToByteArray();
        var index         = bytes.Length - 1;
        var base8         = new StringBuilder((bytes.Length / 3 + 1) * 8);
        var rem           = bytes.Length % 3;
        if (rem == 0) rem = 3;
        var base0         = 0;
        while (rem != 0)
        {
            base0 <<= 8;
            base0 +=  bytes[index--];
            rem--;
        }
        var octal = Convert.ToString(base0, 8);
        if (octal[0] != '0' && bigint.Sign == 1) base8.Append('0');
        base8.Append(octal);
        while (index >= 0)
        {
            base0 = (bytes[index] << 16) + (bytes[index - 1] << 8) + bytes[index - 2];
            base8.Append(Convert.ToString(base0, 8).PadLeft(8, '0'));
            index -= 3;
        }
        return base8.ToString();
    }
    /// <summary>
    ///     Approximation
    /// </summary>
    public static BigInteger Sqrt(this BigInteger n)
    {
        var q = BigInteger.One << ((int) BigInteger.Log(n, 2) >> 1);
        var m = BigInteger.Zero;
        while (BigInteger.Abs(q - m) >= 1)
        {
            m = q;
            q = (m + n / m) >> 1;
        }
        return q;
    }
}

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(' ');
    }
}