diff --git a/src/Science.Cryptography.Ciphers/Alphabet.cs b/src/Science.Cryptography.Ciphers/Alphabet.cs index 6a4bc43..db283bf 100644 --- a/src/Science.Cryptography.Ciphers/Alphabet.cs +++ b/src/Science.Cryptography.Ciphers/Alphabet.cs @@ -1,4 +1,5 @@ using System; +using System.Buffers; using System.Collections; using System.Collections.Frozen; using System.Collections.Generic; @@ -26,16 +27,42 @@ public Alphabet(ReadOnlySpan characters) } _indexLookupUpper = lookupUpper.ToFrozenDictionary(); - _chars = characters.ToArray(); - _str = new string(characters); + // lower + Span lower = stackalloc char[characters.Length]; + characters.ToLowerInvariant(lower); + _lower = new string(lower); + _searchValuesLowercase = SearchValues.Create(lower); + + // upper + Span upper = stackalloc char[characters.Length]; + characters.ToUpperInvariant(upper); + _upper = new string(upper); + _searchValuesUppercase = SearchValues.Create(upper); + + // all lower upper + Span all = stackalloc char[characters.Length * 2]; + characters.ToLowerInvariant(all[..characters.Length]); + characters.ToUpperInvariant(all[characters.Length..]); + _searchValuesIgnoreCase = SearchValues.Create(all); + + // precalculate modulo values DoubleLength = characters.Length * 2; MinusLength = -characters.Length; + + // store + _chars = characters.ToArray(); + _str = new string(characters); } private readonly char[] _chars; private readonly string _str; + private readonly string _lower; + private readonly string _upper; private readonly FrozenDictionary _indexLookup; private readonly FrozenDictionary _indexLookupUpper; + private readonly SearchValues _searchValuesLowercase; + private readonly SearchValues _searchValuesUppercase; + private readonly SearchValues _searchValuesIgnoreCase; private readonly int DoubleLength; private readonly int MinusLength; @@ -154,6 +181,10 @@ public char AtMod(int index) public override string ToString() => _str; + public string ToStringLower() => _lower; + + public string ToStringUpper() => _upper; + public char[] ToCharArray() { var copy = new char[_chars.Length]; @@ -163,6 +194,12 @@ public char[] ToCharArray() public ReadOnlyMemory ToMemory() => _str.AsMemory(); + public SearchValues ToSearchValuesLower() => _searchValuesLowercase; + + public SearchValues ToSearchValuesUpper() => _searchValuesUppercase; + + public SearchValues ToSearchValuesIgnoreCase() => _searchValuesIgnoreCase; + public PolybiusSquare ToPolybiusSquare() => PolybiusSquare.CreateFromAlphabet(this); public void CopyTo(Span destination) => _chars.CopyTo(destination);