diff --git a/src/Sqids/SqidsEncoder.cs b/src/Sqids/SqidsEncoder.cs index 10ed482..28b4899 100644 --- a/src/Sqids/SqidsEncoder.cs +++ b/src/Sqids/SqidsEncoder.cs @@ -110,8 +110,14 @@ public SqidsEncoder(SqidsOptions options) StringComparer.OrdinalIgnoreCase // NOTE: Effectively removes items that differ only in casing — leaves one version of each word casing-wise which will then be compared against the generated IDs case-insensitively ); options.BlockList.RemoveWhere(w => - w.Length < 3 || // NOTE: Removes words that are less than 3 characters long - w.Any(c => !options.Alphabet.Contains(c)) // NOTE: Removes words that contain characters not found in the alphabet + // NOTE: Removes words that are less than 3 characters long + w.Length < 3 || + // NOTE: Removes words that contain characters not found in the alphabet +#if NETSTANDARD2_0 + w.Any(c => options.Alphabet.IndexOf(c.ToString(), StringComparison.OrdinalIgnoreCase) == -1) // NOTE: A `string.Contains` overload with `StringComparison` didn't exist prior to .NET Standard 2.1, so we have to resort to `IndexOf` — see https://stackoverflow.com/a/52791476 +#else + w.Any(c => !options.Alphabet.Contains(c, StringComparison.OrdinalIgnoreCase)) +#endif ); _blockList = options.BlockList.ToArray(); // NOTE: Arrays are faster to iterate than HashSets, so we construct an array here. diff --git a/test/Sqids.Tests/BlockListTests.cs b/test/Sqids.Tests/BlockListTests.cs index 1f95335..080b1dc 100644 --- a/test/Sqids.Tests/BlockListTests.cs +++ b/test/Sqids.Tests/BlockListTests.cs @@ -122,4 +122,24 @@ public void EncodeAndDecode_WithShortCustomBlockList_RoundTripsSuccessfully() sqids.Decode(sqids.Encode(1000)).ShouldBeEquivalentTo(new[] { 1000 }); } + + [Test] + public void EncodeAndDecode_WithLowerCaseBlockListAndUpperCaseAlphabet_IgnoresCasing() + { +#if NET7_0_OR_GREATER + var sqids = new SqidsEncoder(new() +#else + var sqids = new SqidsEncoder(new() +#endif + { + Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + BlockList = new() + { + "sqnmpn", // NOTE: The uppercase version of this is the default encoding of [1,2,3] + }, + }); + + sqids.Encode(1, 2, 3).ShouldBe("ULPBZGBM"); // NOTE: Without the blocklist, would've been "SQNMPN". + sqids.Decode("ULPBZGBM").ShouldBeEquivalentTo(new[] { 1, 2, 3 }); + } }