From 9a41d16e582b612367d785163fc562d688f91aa5 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Mon, 14 Aug 2023 18:43:56 -0400 Subject: [PATCH] ConditionalHashEquals is fun --- SabreTools.Core/DictionaryBaseExtensions.cs | 43 +++++++-------------- SabreTools.Core/Tools/Utilities.cs | 38 +++++++++++++++++- SabreTools.DatItems/DatItem.cs | 20 ---------- SabreTools.DatItems/Formats/File.cs | 8 ++-- SabreTools.Test/DatItems/DatItemTests.cs | 2 +- 5 files changed, 55 insertions(+), 56 deletions(-) diff --git a/SabreTools.Core/DictionaryBaseExtensions.cs b/SabreTools.Core/DictionaryBaseExtensions.cs index f42ae9d1..7965291e 100644 --- a/SabreTools.Core/DictionaryBaseExtensions.cs +++ b/SabreTools.Core/DictionaryBaseExtensions.cs @@ -285,8 +285,8 @@ namespace SabreTools.Core return false; // Return if all hashes match according to merge rules - return ConditionalHashEquals(self.ReadString(Disk.MD5Key), other.ReadString(Disk.MD5Key)) - && ConditionalHashEquals(self.ReadString(Disk.SHA1Key), other.ReadString(Disk.SHA1Key)); + return Tools.Utilities.ConditionalHashEquals(self.ReadString(Disk.MD5Key), other.ReadString(Disk.MD5Key)) + && Tools.Utilities.ConditionalHashEquals(self.ReadString(Disk.SHA1Key), other.ReadString(Disk.SHA1Key)); } /// @@ -303,10 +303,10 @@ namespace SabreTools.Core return false; // Return if all hashes match according to merge rules - return ConditionalHashEquals(self.ReadString(Media.MD5Key), other.ReadString(Media.MD5Key)) - && ConditionalHashEquals(self.ReadString(Media.SHA1Key), other.ReadString(Media.SHA1Key)) - && ConditionalHashEquals(self.ReadString(Media.SHA256Key), other.ReadString(Media.SHA256Key)) - && ConditionalHashEquals(self.ReadString(Media.SpamSumKey), other.ReadString(Media.SpamSumKey)); + return Tools.Utilities.ConditionalHashEquals(self.ReadString(Media.MD5Key), other.ReadString(Media.MD5Key)) + && Tools.Utilities.ConditionalHashEquals(self.ReadString(Media.SHA1Key), other.ReadString(Media.SHA1Key)) + && Tools.Utilities.ConditionalHashEquals(self.ReadString(Media.SHA256Key), other.ReadString(Media.SHA256Key)) + && Tools.Utilities.ConditionalHashEquals(self.ReadString(Media.SpamSumKey), other.ReadString(Media.SpamSumKey)); } /// @@ -323,13 +323,13 @@ namespace SabreTools.Core return false; // Return if all hashes match according to merge rules - return ConditionalHashEquals(self.ReadString(Rom.CRCKey), other.ReadString(Rom.CRCKey)) - && ConditionalHashEquals(self.ReadString(Rom.MD5Key), other.ReadString(Rom.MD5Key)) - && ConditionalHashEquals(self.ReadString(Rom.SHA1Key), other.ReadString(Rom.SHA1Key)) - && ConditionalHashEquals(self.ReadString(Rom.SHA256Key), other.ReadString(Rom.SHA256Key)) - && ConditionalHashEquals(self.ReadString(Rom.SHA384Key), other.ReadString(Rom.SHA384Key)) - && ConditionalHashEquals(self.ReadString(Rom.SHA512Key), other.ReadString(Rom.SHA512Key)) - && ConditionalHashEquals(self.ReadString(Rom.SpamSumKey), other.ReadString(Rom.SpamSumKey)); + return Tools.Utilities.ConditionalHashEquals(self.ReadString(Rom.CRCKey), other.ReadString(Rom.CRCKey)) + && Tools.Utilities.ConditionalHashEquals(self.ReadString(Rom.MD5Key), other.ReadString(Rom.MD5Key)) + && Tools.Utilities.ConditionalHashEquals(self.ReadString(Rom.SHA1Key), other.ReadString(Rom.SHA1Key)) + && Tools.Utilities.ConditionalHashEquals(self.ReadString(Rom.SHA256Key), other.ReadString(Rom.SHA256Key)) + && Tools.Utilities.ConditionalHashEquals(self.ReadString(Rom.SHA384Key), other.ReadString(Rom.SHA384Key)) + && Tools.Utilities.ConditionalHashEquals(self.ReadString(Rom.SHA512Key), other.ReadString(Rom.SHA512Key)) + && Tools.Utilities.ConditionalHashEquals(self.ReadString(Rom.SpamSumKey), other.ReadString(Rom.SpamSumKey)); } /// @@ -435,23 +435,6 @@ namespace SabreTools.Core return crcNull && md5Null && sha1Null && sha256Null && sha384Null && sha512Null && spamsumNull; } - /// - /// Determine if two hashes are equal for the purposes of merging - /// - private static bool ConditionalHashEquals(string? firstHash, string? secondHash) - { - // If either hash is empty, we say they're equal for merging - if (string.IsNullOrWhiteSpace(firstHash) || string.IsNullOrWhiteSpace(secondHash)) - return true; - - // If they're different sizes, they can't match - if (firstHash!.Length != secondHash!.Length) - return false; - - // Otherwise, they need to match exactly - return string.Equals(firstHash, secondHash, StringComparison.OrdinalIgnoreCase); - } - /// /// Returns if there are no, non-empty hashes in common /// diff --git a/SabreTools.Core/Tools/Utilities.cs b/SabreTools.Core/Tools/Utilities.cs index 0afe6d4a..26f2b4ff 100644 --- a/SabreTools.Core/Tools/Utilities.cs +++ b/SabreTools.Core/Tools/Utilities.cs @@ -1,4 +1,6 @@ -using System.IO; +using System; +using System.IO; +using System.Linq; namespace SabreTools.Core.Tools { @@ -7,6 +9,40 @@ namespace SabreTools.Core.Tools /// public static class Utilities { + /// + /// Determine if two hashes are equal for the purposes of merging + /// + public static bool ConditionalHashEquals(byte[]? firstHash, byte[]? secondHash) + { + // If either hash is empty, we say they're equal for merging + if (firstHash.IsNullOrEmpty() || secondHash.IsNullOrEmpty()) + return true; + + // If they're different sizes, they can't match + if (firstHash!.Length != secondHash!.Length) + return false; + + // Otherwise, they need to match exactly + return Enumerable.SequenceEqual(firstHash, secondHash); + } + + /// + /// Determine if two hashes are equal for the purposes of merging + /// + public static bool ConditionalHashEquals(string? firstHash, string? secondHash) + { + // If either hash is empty, we say they're equal for merging + if (string.IsNullOrWhiteSpace(firstHash) || string.IsNullOrWhiteSpace(secondHash)) + return true; + + // If they're different sizes, they can't match + if (firstHash!.Length != secondHash!.Length) + return false; + + // Otherwise, they need to match exactly + return string.Equals(firstHash, secondHash, StringComparison.OrdinalIgnoreCase); + } + /// /// Get a proper romba sub path /// diff --git a/SabreTools.DatItems/DatItem.cs b/SabreTools.DatItems/DatItem.cs index 97db2745..59ad94ba 100644 --- a/SabreTools.DatItems/DatItem.cs +++ b/SabreTools.DatItems/DatItem.cs @@ -399,26 +399,6 @@ namespace SabreTools.DatItems #region Sorting and Merging - /// - /// Determine if two hashes are equal for the purposes of merging - /// - /// First hash to compare - /// Second hash to compare - /// True if either is empty OR the hashes exactly match, false otherwise - public static bool ConditionalHashEquals(byte[]? firstHash, byte[]? secondHash) - { - // If either hash is empty, we say they're equal for merging - if (firstHash.IsNullOrEmpty() || secondHash.IsNullOrEmpty()) - return true; - - // If they're different sizes, they can't match - if (firstHash!.Length != secondHash!.Length) - return false; - - // Otherwise, they need to match exactly - return Enumerable.SequenceEqual(firstHash, secondHash); - } - /// /// Merge an arbitrary set of ROMs based on the supplied information /// diff --git a/SabreTools.DatItems/Formats/File.cs b/SabreTools.DatItems/Formats/File.cs index 65c455ce..280bc282 100644 --- a/SabreTools.DatItems/Formats/File.cs +++ b/SabreTools.DatItems/Formats/File.cs @@ -317,10 +317,10 @@ namespace SabreTools.DatItems.Formats return false; // Return if all hashes match according to merge rules - return ConditionalHashEquals(_crc, other._crc) - && ConditionalHashEquals(_md5, other._md5) - && ConditionalHashEquals(_sha1, other._sha1) - && ConditionalHashEquals(_sha256, other._sha256); + return Utilities.ConditionalHashEquals(_crc, other._crc) + && Utilities.ConditionalHashEquals(_md5, other._md5) + && Utilities.ConditionalHashEquals(_sha1, other._sha1) + && Utilities.ConditionalHashEquals(_sha256, other._sha256); } #endregion diff --git a/SabreTools.Test/DatItems/DatItemTests.cs b/SabreTools.Test/DatItems/DatItemTests.cs index ca0b71d9..764403c4 100644 --- a/SabreTools.Test/DatItems/DatItemTests.cs +++ b/SabreTools.Test/DatItems/DatItemTests.cs @@ -189,7 +189,7 @@ namespace SabreTools.Test.DatItems [InlineData(new byte[] { 0x00 }, new byte[] { 0x00 }, true)] public void ConditionalHashEqualsTest(byte[] first, byte[] second, bool expected) { - bool actual = DatItem.ConditionalHashEquals(first, second); + bool actual = SabreTools.Core.Tools.Utilities.ConditionalHashEquals(first, second); Assert.Equal(expected, actual); }