Skip to content

Commit

Permalink
Check blocked words against alphabet case-insensitively (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
aradalvand authored Aug 30, 2023
1 parent 5217f58 commit d800a46
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/Sqids/SqidsEncoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
20 changes: 20 additions & 0 deletions test/Sqids.Tests/BlockListTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<int>(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 });
}
}

0 comments on commit d800a46

Please sign in to comment.