diff --git a/src/.idea/.idea.Microsoft.Security.Utilities/.idea/.gitignore b/src/.idea/.idea.Microsoft.Security.Utilities/.idea/.gitignore new file mode 100644 index 00000000..877a2f12 --- /dev/null +++ b/src/.idea/.idea.Microsoft.Security.Utilities/.idea/.gitignore @@ -0,0 +1,13 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/modules.xml +/contentModel.xml +/projectSettingsUpdater.xml +/.idea.Microsoft.Security.Utilities.iml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/src/.idea/.idea.Microsoft.Security.Utilities/.idea/.name b/src/.idea/.idea.Microsoft.Security.Utilities/.idea/.name new file mode 100644 index 00000000..82629046 --- /dev/null +++ b/src/.idea/.idea.Microsoft.Security.Utilities/.idea/.name @@ -0,0 +1 @@ +Microsoft.Security.Utilities \ No newline at end of file diff --git a/src/.idea/.idea.Microsoft.Security.Utilities/.idea/encodings.xml b/src/.idea/.idea.Microsoft.Security.Utilities/.idea/encodings.xml new file mode 100644 index 00000000..df87cf95 --- /dev/null +++ b/src/.idea/.idea.Microsoft.Security.Utilities/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/src/.idea/.idea.Microsoft.Security.Utilities/.idea/indexLayout.xml b/src/.idea/.idea.Microsoft.Security.Utilities/.idea/indexLayout.xml new file mode 100644 index 00000000..7b08163c --- /dev/null +++ b/src/.idea/.idea.Microsoft.Security.Utilities/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/.idea/.idea.Microsoft.Security.Utilities/.idea/vcs.xml b/src/.idea/.idea.Microsoft.Security.Utilities/.idea/vcs.xml new file mode 100644 index 00000000..6c0b8635 --- /dev/null +++ b/src/.idea/.idea.Microsoft.Security.Utilities/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/Microsoft.Security.Utilities/CustomAlphabetEncoder.cs b/src/Microsoft.Security.Utilities/CustomAlphabetEncoder.cs index c1d044ff..d04ce7ab 100644 --- a/src/Microsoft.Security.Utilities/CustomAlphabetEncoder.cs +++ b/src/Microsoft.Security.Utilities/CustomAlphabetEncoder.cs @@ -115,5 +115,41 @@ public byte[] Decode(string encodedValue) return BitConverter.GetBytes(decodedValue); } + + /// + /// Sets a custom alphabet to be used for all encoding and decoding operations. + /// + /// A string representing the custom alphabet. It must consist of non-whitespace ASCII characters, including letters, numbers, and/or punctuation. + /// Throws an exception if the alphabet contains duplicates or contains forbidden characters. + /// + /// This method allows dynamic changes to the alphabet used for encoding and decoding data. Before setting a new alphabet, the method performs checks for duplicates and the presence of forbidden characters. + /// + public void SetCustomAlphabet(string customAlphabet) + { + if (customAlphabet == null) + { + throw new ArgumentNullException(nameof(customAlphabet)); + } + + Dictionary newCharToValueMap = new Dictionary(); + + for (int i = 0; i < customAlphabet.Length; i++) + { + if (newCharToValueMap.ContainsKey(customAlphabet[i])) + { + throw new ArgumentException(nameof(customAlphabet), "Duplicate value detected in the new alphabet."); + } + + if (Char.IsWhiteSpace(customAlphabet[i]) || Char.IsSurrogate(customAlphabet[i]) || (int)customAlphabet[i] > 127) + { + throw new ArgumentException(nameof(customAlphabet), $"Forbidden character type detected in the new alphabet: {customAlphabet[i]}."); + } + + newCharToValueMap[customAlphabet[i]] = (uint)i; + } + + alphabet = customAlphabet; + charToValueMap = newCharToValueMap; + } } } diff --git a/src/Microsoft.Security.Utilities/Microsoft.Security.Utilities.csproj b/src/Microsoft.Security.Utilities/Microsoft.Security.Utilities.csproj index e9af6ed7..bdf1b999 100644 --- a/src/Microsoft.Security.Utilities/Microsoft.Security.Utilities.csproj +++ b/src/Microsoft.Security.Utilities/Microsoft.Security.Utilities.csproj @@ -18,6 +18,10 @@ true + + C:\Users\User\RiderProjects\Fork\bld\bin\AnyCPU_Debug\Microsoft.Security.Utilities\Microsoft.Security.Utilities.xml + + diff --git a/src/Tests.Microsoft.Security.Utilities/CustomAlphabetEncoderTests.cs b/src/Tests.Microsoft.Security.Utilities/CustomAlphabetEncoderTests.cs index 28f75665..d2e96826 100644 --- a/src/Tests.Microsoft.Security.Utilities/CustomAlphabetEncoderTests.cs +++ b/src/Tests.Microsoft.Security.Utilities/CustomAlphabetEncoderTests.cs @@ -198,6 +198,23 @@ public void CustomAlphabetEncoder_VerifyStaticAndInstanceDate() encodedChecksum1.Should().Be(encodedChecksum2); } + + [TestMethod] + public void CustomAlphabetEncoder_SetCustomAlphabetShouldChangeAlphabetAndWorkCorrectly() + { + var testEncoder = new CustomAlphabetEncoder("123"); + uint input = 42; + string originalEncoded = testEncoder.Encode(input); + + testEncoder.SetCustomAlphabet("ABC"); + + string newEncoded = testEncoder.Encode(input); + byte[] newDecoded = testEncoder.Decode(newEncoded); + uint newDecodedUint = BitConverter.ToUInt32(newDecoded, 0); + + newEncoded.Should().NotBe(originalEncoded); + newDecodedUint.Should().Be(input); + } private IEnumerable GenerateValidAlphabetTestCases() {