From 3c035dd4408ce578870b659278d6ae3d5c10cba6 Mon Sep 17 00:00:00 2001 From: BoBoBaSs84 <73112377+BoBoBaSs84@users.noreply.github.com> Date: Mon, 30 Sep 2024 07:45:04 +0200 Subject: [PATCH 1/2] feat: byte array to base64 extension methods added --- .../ByteExtensions.FromBase64.cs | 27 +++++++++++++++++++ .../ByteExtensions.ToBase64.cs | 13 +++++++++ src/BB84.Extensions/ByteExtensions.cs | 15 +++++++++-- .../StringExtensions.FromBase64.cs | 17 +++--------- .../StringExtensions.ToBase64.cs | 5 ++-- src/BB84.Extensions/StringExtensions.cs | 5 ---- 6 files changed, 58 insertions(+), 24 deletions(-) create mode 100644 src/BB84.Extensions/ByteExtensions.FromBase64.cs create mode 100644 src/BB84.Extensions/ByteExtensions.ToBase64.cs diff --git a/src/BB84.Extensions/ByteExtensions.FromBase64.cs b/src/BB84.Extensions/ByteExtensions.FromBase64.cs new file mode 100644 index 0000000..1a699a7 --- /dev/null +++ b/src/BB84.Extensions/ByteExtensions.FromBase64.cs @@ -0,0 +1,27 @@ +namespace BB84.Extensions; + +public static partial class ByteExtensions +{ + /// + /// Converts the specified , which encodes binary data as base-64 digits, + /// to an equivalent 8-bit unsigned integer array. + /// + /// The string to convert. + /// An array of 8-bit unsigned integers that is equivalent to . + /// + public static byte[] FromBase64(this string value) + { + if (value.IsNullOrEmpty()) + return []; + + value = value.Trim(); + bool isValidBase64 = (value.Length % 4 == 0) && Base64Regex.IsMatch(value); + + if (isValidBase64.Equals(false)) + throw new ArgumentException($"{value} is not valid base64"); + + byte[] bytes = Convert.FromBase64String(value); + + return bytes; + } +} diff --git a/src/BB84.Extensions/ByteExtensions.ToBase64.cs b/src/BB84.Extensions/ByteExtensions.ToBase64.cs new file mode 100644 index 0000000..13267b0 --- /dev/null +++ b/src/BB84.Extensions/ByteExtensions.ToBase64.cs @@ -0,0 +1,13 @@ +namespace BB84.Extensions; + +public static partial class ByteExtensions +{ + /// + /// Converts an array of 8-bit unsigned integers to its equivalent string representation + /// that is encoded with base-64 digits. + /// + /// An array of 8-bit unsigned integers. + /// The string representation, in base 64, of the contents of . + public static string ToBase64(this byte[] byteArray) + => byteArray.Length.Equals(0) ? string.Empty : Convert.ToBase64String(byteArray); +} diff --git a/src/BB84.Extensions/ByteExtensions.cs b/src/BB84.Extensions/ByteExtensions.cs index 42777fc..6189ec0 100644 --- a/src/BB84.Extensions/ByteExtensions.cs +++ b/src/BB84.Extensions/ByteExtensions.cs @@ -1,7 +1,18 @@ -namespace BB84.Extensions; +using System.Text.RegularExpressions; + +namespace BB84.Extensions; /// /// The byte extensions class. /// public static partial class ByteExtensions -{ } +{ +#if NET7_0_OR_GREATER + private static readonly Regex Base64Regex = GeneratedBase64Regex(); + + [GeneratedRegex(@"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None)] + private static partial Regex GeneratedBase64Regex(); +#else + private static readonly Regex Base64Regex = new(@"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None); +#endif +} diff --git a/src/BB84.Extensions/StringExtensions.FromBase64.cs b/src/BB84.Extensions/StringExtensions.FromBase64.cs index c97f9a5..308ad30 100644 --- a/src/BB84.Extensions/StringExtensions.FromBase64.cs +++ b/src/BB84.Extensions/StringExtensions.FromBase64.cs @@ -7,24 +7,13 @@ public static partial class StringExtensions /// /// Decodes the provided string from a base64 string. /// - /// The input string to work with. + /// The input string to work with. /// The encoding to use. /// The decoded string. /// The provided string is not a valid base64 string. - public static string FromBase64(this string stringValue, Encoding? encoding = null) + public static string FromBase64(this string value, Encoding encoding) { - if (stringValue.IsNullOrEmpty()) - return string.Empty; - - // Check for valid base64 - stringValue = stringValue.Trim(); - bool isValidBase64 = (stringValue.Length % 4 == 0) && Base64Regex.IsMatch(stringValue); - - if (isValidBase64.Equals(false)) - throw new ArgumentException($"{stringValue} is not valid base64"); - - byte[] buffer = Convert.FromBase64String(stringValue); - encoding ??= Encoding.Default; + byte[] buffer = value.FromBase64(); return encoding.GetString(buffer); } } diff --git a/src/BB84.Extensions/StringExtensions.ToBase64.cs b/src/BB84.Extensions/StringExtensions.ToBase64.cs index c1bb0bd..647ca7e 100644 --- a/src/BB84.Extensions/StringExtensions.ToBase64.cs +++ b/src/BB84.Extensions/StringExtensions.ToBase64.cs @@ -10,13 +10,12 @@ public static partial class StringExtensions /// The input string to work with. /// The encoding to use. /// The encoded string. - public static string ToBase64(this string stringValue, Encoding? encoding = null) + public static string ToBase64(this string stringValue, Encoding encoding) { if (stringValue.IsNullOrWhiteSpace()) return string.Empty; - encoding ??= Encoding.Default; byte[] buffer = encoding.GetBytes(stringValue); - return Convert.ToBase64String(buffer); + return buffer.ToBase64(); } } diff --git a/src/BB84.Extensions/StringExtensions.cs b/src/BB84.Extensions/StringExtensions.cs index 4cf00e1..1afdb99 100644 --- a/src/BB84.Extensions/StringExtensions.cs +++ b/src/BB84.Extensions/StringExtensions.cs @@ -8,20 +8,15 @@ namespace BB84.Extensions; public static partial class StringExtensions { #if NET7_0_OR_GREATER - private static readonly Regex Base64Regex = GeneratedBase64Regex(); private static readonly Regex WhitespaceRegex = GeneratedWhitespaceRegex(); private static readonly Regex LinebreakRegex = GeneratedLinebreakRegex(); - [GeneratedRegex(@"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None)] - private static partial Regex GeneratedBase64Regex(); - [GeneratedRegex(@"\s+", RegexOptions.None)] private static partial Regex GeneratedWhitespaceRegex(); [GeneratedRegex(@"(\r\n|\r|\n)", RegexOptions.None)] private static partial Regex GeneratedLinebreakRegex(); #else - private static readonly Regex Base64Regex = new(@"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None); private static readonly Regex WhitespaceRegex = new(@"\s+", RegexOptions.None); private static readonly Regex LinebreakRegex = new(@"(\r\n|\r|\n)", RegexOptions.None); #endif From 6e250f04388f647cfea41d52aaf671562e9815c6 Mon Sep 17 00:00:00 2001 From: BoBoBaSs84 <73112377+BoBoBaSs84@users.noreply.github.com> Date: Mon, 30 Sep 2024 07:45:29 +0200 Subject: [PATCH 2/2] feat: extension methods unit tests added --- .../ByteExtensionsTests.FromBase64.cs | 12 +++++ .../ByteExtensionsTests.ToBase64.cs | 12 +++++ .../StringExtensionsTests.FromBase64.cs | 44 +++++++------------ .../StringExtensionsTests.ToBase64.cs | 29 ++++-------- 4 files changed, 47 insertions(+), 50 deletions(-) create mode 100644 tests/BB84.ExtensionsTests/ByteExtensionsTests.FromBase64.cs create mode 100644 tests/BB84.ExtensionsTests/ByteExtensionsTests.ToBase64.cs diff --git a/tests/BB84.ExtensionsTests/ByteExtensionsTests.FromBase64.cs b/tests/BB84.ExtensionsTests/ByteExtensionsTests.FromBase64.cs new file mode 100644 index 0000000..2adea75 --- /dev/null +++ b/tests/BB84.ExtensionsTests/ByteExtensionsTests.FromBase64.cs @@ -0,0 +1,12 @@ +using BB84.Extensions; + +namespace BB84.ExtensionsTests; + +public sealed partial class ByteExtensionsTests +{ + [DataTestMethod] + [DataRow(new byte[] { 85, 110, 105, 116, 84, 101, 115, 116 }, "VW5pdFRlc3Q=")] + [DataRow(new byte[0], "")] + public void FromBase64Test(byte[] expected, string value) + => Assert.IsTrue(expected.SequenceEqual(value.FromBase64())); +} diff --git a/tests/BB84.ExtensionsTests/ByteExtensionsTests.ToBase64.cs b/tests/BB84.ExtensionsTests/ByteExtensionsTests.ToBase64.cs new file mode 100644 index 0000000..25e8d14 --- /dev/null +++ b/tests/BB84.ExtensionsTests/ByteExtensionsTests.ToBase64.cs @@ -0,0 +1,12 @@ +using BB84.Extensions; + +namespace BB84.ExtensionsTests; + +public sealed partial class ByteExtensionsTests +{ + [DataTestMethod] + [DataRow("VW5pdFRlc3Q=", new byte[] { 85, 110, 105, 116, 84, 101, 115, 116 })] + [DataRow("", new byte[0])] + public void ToBase64Test(string expected, byte[] bytes) + => Assert.AreEqual(expected, bytes.ToBase64()); +} diff --git a/tests/BB84.ExtensionsTests/StringExtensionsTests.FromBase64.cs b/tests/BB84.ExtensionsTests/StringExtensionsTests.FromBase64.cs index 7ed8ef1..9eb5935 100644 --- a/tests/BB84.ExtensionsTests/StringExtensionsTests.FromBase64.cs +++ b/tests/BB84.ExtensionsTests/StringExtensionsTests.FromBase64.cs @@ -1,36 +1,22 @@ -using BB84.Extensions; +using System.Text; + +using BB84.Extensions; namespace BB84.ExtensionsTests; public sealed partial class StringExtensionsTests { - [TestMethod] - public void FromBase64Test() - { - string value = "VW5pdFRlc3Q="; - - string result = value.FromBase64(); - - Assert.AreNotEqual(value, result); - Assert.AreEqual("UnitTest", result); - } - - [TestMethod] - public void FromBase64EmptyTest() - { - string value = string.Empty; - - string result = value.FromBase64(); - - Assert.AreEqual(value, result); - } - - [TestMethod] + [DataTestMethod] + [DataRow("UnitTest", "VW5pdFRlc3Q=")] + [DataRow("", "")] + public void FromBase64Test(string expected, string value) + => Assert.AreEqual(expected, value.FromBase64(Encoding.UTF8)); + + [DataTestMethod] + [DataRow("%")] + [DataRow("$")] + [DataRow("#")] [ExpectedException(typeof(ArgumentException))] - public void FromBase64ExceptionTest() - { - string value = "%$#"; - - _ = value.FromBase64(); - } + public void FromBase64ExceptionTest(string value) + => value.FromBase64(); } diff --git a/tests/BB84.ExtensionsTests/StringExtensionsTests.ToBase64.cs b/tests/BB84.ExtensionsTests/StringExtensionsTests.ToBase64.cs index 70bf118..97f3fd9 100644 --- a/tests/BB84.ExtensionsTests/StringExtensionsTests.ToBase64.cs +++ b/tests/BB84.ExtensionsTests/StringExtensionsTests.ToBase64.cs @@ -1,27 +1,14 @@ -using BB84.Extensions; +using System.Text; + +using BB84.Extensions; namespace BB84.ExtensionsTests; public sealed partial class StringExtensionsTests { - [TestMethod] - public void ToBase64Test() - { - string value = "UnitTest"; - - string result = value.ToBase64(); - - Assert.AreNotEqual(value, result); - Assert.AreEqual("VW5pdFRlc3Q=", result); - } - - [TestMethod] - public void ToBase64EmptyTest() - { - string value = string.Empty; - - string result = value.ToBase64(); - - Assert.AreEqual(value, result); - } + [DataTestMethod] + [DataRow("VW5pdFRlc3Q=", "UnitTest")] + [DataRow("", "")] + public void ToBase64Test(string expected, string value) + => Assert.AreEqual(expected, value.ToBase64(Encoding.UTF8)); }