diff --git a/src/BizHawk.BizInvoke/WaterboxUtils.cs b/src/BizHawk.BizInvoke/WaterboxUtils.cs index 89eef14588..a0c2c11f83 100644 --- a/src/BizHawk.BizInvoke/WaterboxUtils.cs +++ b/src/BizHawk.BizInvoke/WaterboxUtils.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using System.Security.Cryptography; namespace BizHawk.BizInvoke { @@ -22,18 +21,6 @@ namespace BizHawk.BizInvoke } } - public static byte[] Hash(byte[] data) - { - using var h = SHA1.Create(); - return h.ComputeHash(data); - } - - public static byte[] Hash(Stream s) - { - using var h = SHA1.Create(); - return h.ComputeHash(s); - } - public static unsafe void ZeroMemory(IntPtr mem, long length) { byte* p = (byte*)mem; diff --git a/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs b/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs index 3d184d73c3..70257ed557 100644 --- a/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs +++ b/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs @@ -1,10 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Security.Cryptography; using BizHawk.Common; -using BizHawk.Common.BufferExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -235,8 +233,7 @@ namespace BizHawk.Client.Common } var data = new byte[count]; for (var i = 0; i < count; i++) data[i] = d.PeekByte(addr + i); - using var hasher = SHA256.Create(); - return hasher.ComputeHash(data).BytesToHexString(); + return SHA256Checksum.ComputeDigestHex(data); } public uint ReadByte(long addr, string domain = null) => ReadUnsigned(addr, 1, domain); diff --git a/src/BizHawk.Client.Common/RomLoader.cs b/src/BizHawk.Client.Common/RomLoader.cs index 954085c0d4..94456429b9 100644 --- a/src/BizHawk.Client.Common/RomLoader.cs +++ b/src/BizHawk.Client.Common/RomLoader.cs @@ -233,7 +233,7 @@ namespace BizHawk.Client.Common var discType = new DiscIdentifier(disc).DetectDiscType(); var discHasher = new DiscHasher(disc); var discHash = discType == DiscType.SonyPSX - ? discHasher.Calculate_PSX_BizIDHash().ToString("X8") + ? discHasher.Calculate_PSX_BizIDHash() : discHasher.OldHash(); var game = Database.CheckDatabase(discHash); diff --git a/src/BizHawk.Client.Common/XmlGame.cs b/src/BizHawk.Client.Common/XmlGame.cs index 2d49abadb7..28cbd18c55 100644 --- a/src/BizHawk.Client.Common/XmlGame.cs +++ b/src/BizHawk.Client.Common/XmlGame.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Xml; using BizHawk.Common; -using BizHawk.Common.BufferExtensions; using BizHawk.Common.IOExtensions; using BizHawk.Emulation.Common; @@ -99,12 +98,11 @@ namespace BizHawk.Client.Common ret.Assets.Add(new KeyValuePair(filename, data)); ret.AssetFullPaths.Add(fullPath); - using var sha1 = System.Security.Cryptography.SHA1.Create(); - sha1.TransformFinalBlock(data, 0, data.Length); - hashStream.Write(sha1.Hash, 0, sha1.Hash.Length); + var sha1 = SHA1Checksum.Compute(data); + hashStream.Write(sha1, 0, sha1.Length); } - ret.GI.Hash = hashStream.GetBuffer().HashSHA1(0, (int)hashStream.Length); + ret.GI.Hash = SHA1Checksum.ComputeDigestHex(hashStream.GetBufferAsSpan()); hashStream.Close(); if (originalIndex != null) { diff --git a/src/BizHawk.Client.Common/fwmanager/FirmwareManager.cs b/src/BizHawk.Client.Common/fwmanager/FirmwareManager.cs index 4be60859db..204127e997 100644 --- a/src/BizHawk.Client.Common/fwmanager/FirmwareManager.cs +++ b/src/BizHawk.Client.Common/fwmanager/FirmwareManager.cs @@ -1,14 +1,13 @@ #nullable enable -using System; using System.Collections.Generic; using System.Diagnostics; -using System.Security.Cryptography; using System.IO; using System.Linq; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Common.CollectionExtensions; +using BizHawk.Common.IOExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -20,9 +19,7 @@ namespace BizHawk.Client.Common public static (byte[] Patched, string ActualHash) PerformPatchInMemory(byte[] @base, in FirmwarePatchOption patchOption) { var patched = patchOption.Patches.Aggregate(seed: @base, (a, fpd) => fpd.ApplyToMutating(a)); - using var sha1 = SHA1.Create(); - sha1.ComputeHash(patched); - return (patched, sha1.Hash.BytesToHexString()); + return (patched, SHA1Checksum.ComputeDigestHex(patched)); } public static (string FilePath, int FileSize, FirmwareFile FF) PerformPatchOnDisk(string baseFilename, in FirmwarePatchOption patchOption, PathEntryCollection pathEntries) @@ -95,26 +92,16 @@ namespace BizHawk.Client.Common return resolved.FilePath; } - private sealed class RealFirmwareReader : IDisposable + private sealed class RealFirmwareReader { private readonly Dictionary _dict = new(); - private SHA1? _sha1 = SHA1.Create(); - public IReadOnlyDictionary Dict => _dict; - public void Dispose() - { - _sha1?.Dispose(); - _sha1 = null; - } - public RealFirmwareFile Read(FileInfo fi) { - if (_sha1 == null) throw new ObjectDisposedException(nameof(RealFirmwareReader)); using var fs = fi.OpenRead(); - _sha1!.ComputeHash(fs); - var hash = _sha1.Hash.BytesToHexString(); + var hash = SHA1Checksum.ComputeDigestHex(fs.ReadAllBytes()); return _dict![hash] = new RealFirmwareFile(fi, hash); } } @@ -133,7 +120,7 @@ namespace BizHawk.Client.Common if (!_firmwareSizes.Contains(fi.Length)) return false; // check the hash - using var reader = new RealFirmwareReader(); + var reader = new RealFirmwareReader(); reader.Read(fi); var hash = reader.Dict.Values.First().Hash; return FirmwareDatabase.FirmwareFiles.Any(a => a.Hash == hash); @@ -146,7 +133,7 @@ namespace BizHawk.Client.Common public void DoScanAndResolve(PathEntryCollection pathEntries, IDictionary userSpecifications) { - using var reader = new RealFirmwareReader(); + var reader = new RealFirmwareReader(); // build a list of files under the global firmwares path, and build a hash for each of them (as ResolutionInfo) while we're at it var todo = new Queue(new[] { new DirectoryInfo(pathEntries.AbsolutePathFor(pathEntries.FirmwaresPathFragment, null)) }); diff --git a/src/BizHawk.Client.EmuHawk/MainForm.Debug.cs b/src/BizHawk.Client.EmuHawk/MainForm.Debug.cs index dd1c912c32..47bb9231c2 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.Debug.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.Debug.cs @@ -5,12 +5,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; -using System.Security.Cryptography; using System.Windows.Forms; using BizHawk.Client.Common; using BizHawk.Client.EmuHawk.Properties; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores; using BizHawk.Emulation.Cores.Nintendo.GBA; @@ -88,9 +87,7 @@ namespace BizHawk.Client.EmuHawk return; } // else something happened, figure out what it was - using var sha1 = SHA1.Create(); - sha1.ComputeHash(@base); - var baseHash = sha1.Hash.BytesToHexString(); + var baseHash = SHA1Checksum.ComputeDigestHex(@base); this.ModalMessageBox(baseHash == fpo.BaseHash ? $"patchset declared with target\nSHA1:{fpo.TargetHash}\nbut produced\nSHA1:{actualHash}\n(is the patch wrong, or the hash?)" : $"patchset declared for base\nSHA1:{fpo.BaseHash}\nbut\nSHA1:{baseHash}\nwas provided"); diff --git a/src/BizHawk.Client.EmuHawk/MainForm.cs b/src/BizHawk.Client.EmuHawk/MainForm.cs index fad454fd52..0b5a02e774 100644 --- a/src/BizHawk.Client.EmuHawk/MainForm.cs +++ b/src/BizHawk.Client.EmuHawk/MainForm.cs @@ -3822,8 +3822,9 @@ namespace BizHawk.Client.EmuHawk else { xSw.WriteLine(xmlGame.Assets[xg].Key); - xSw.WriteLine($"SHA1:{xmlGame.Assets[xg].Value.HashSHA1()}"); - xSw.WriteLine($"MD5:{xmlGame.Assets[xg].Value.HashMD5()}"); + var data = xmlGame.Assets[xg].Value; + xSw.WriteLine(SHA1Checksum.ComputePrefixedHex(data)); + xSw.WriteLine(MD5Checksum.ComputePrefixedHex(data)); xSw.WriteLine(); } } @@ -3857,7 +3858,7 @@ namespace BizHawk.Client.EmuHawk var romDetails = Emulator.RomDetails(); if (string.IsNullOrWhiteSpace(romDetails) && loader.Rom != null) { - _defaultRomDetails = $"{loader.Game.Name}\r\nSHA1:{loader.Rom.RomData.HashSHA1()}\r\nMD5:{loader.Rom.RomData.HashMD5()}\r\n"; + _defaultRomDetails = $"{loader.Game.Name}\r\n{SHA1Checksum.ComputePrefixedHex(loader.Rom.RomData)}\r\n{MD5Checksum.ComputePrefixedHex(loader.Rom.RomData)}\r\n"; } else if (string.IsNullOrWhiteSpace(romDetails) && loader.Rom == null) { diff --git a/src/BizHawk.Client.EmuHawk/tools/PCE/PCESoundDebugger.cs b/src/BizHawk.Client.EmuHawk/tools/PCE/PCESoundDebugger.cs index 1e92d53542..ae2f5aabcc 100644 --- a/src/BizHawk.Client.EmuHawk/tools/PCE/PCESoundDebugger.cs +++ b/src/BizHawk.Client.EmuHawk/tools/PCE/PCESoundDebugger.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.Windows.Forms; using BizHawk.Client.Common; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Cores.PCEngine; using BizHawk.Emulation.Common; @@ -103,7 +103,7 @@ namespace BizHawk.Client.EmuHawk } bw.Flush(); - string md5 = _waveformTemp.HashMD5(); + var md5 = MD5Checksum.ComputeDigestHex(_waveformTemp); if (!_psgEntryTable.TryGetValue(md5, out var entry)) { diff --git a/src/BizHawk.Common/Extensions/BufferExtensions.cs b/src/BizHawk.Common/Extensions/BufferExtensions.cs index dbf7c3751f..b0a0c2b1f1 100644 --- a/src/BizHawk.Common/Extensions/BufferExtensions.cs +++ b/src/BizHawk.Common/Extensions/BufferExtensions.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.Text; -using System.Security.Cryptography; namespace BizHawk.Common.BufferExtensions { @@ -77,30 +76,6 @@ namespace BizHawk.Common.BufferExtensions return result >= pattern.Length - 1; } - public static string HashMD5(this byte[] data, int offset, int len) - { - using var md5 = MD5.Create(); - md5.ComputeHash(data, offset, len); - return md5.Hash.BytesToHexString(); - } - - public static string HashMD5(this byte[] data) - { - return HashMD5(data, 0, data.Length); - } - - public static string HashSHA1(this byte[] data, int offset, int len) - { - using var sha1 = SHA1.Create(); - sha1.ComputeHash(data, offset, len); - return sha1.Hash.BytesToHexString(); - } - - public static string HashSHA1(this byte[] data) - { - return HashSHA1(data, 0, data.Length); - } - private static int Hex2Int(char c) { if (c <= '9') diff --git a/src/BizHawk.Common/Extensions/IOExtensions.cs b/src/BizHawk.Common/Extensions/IOExtensions.cs index 7c52de6917..e066409bbc 100644 --- a/src/BizHawk.Common/Extensions/IOExtensions.cs +++ b/src/BizHawk.Common/Extensions/IOExtensions.cs @@ -1,10 +1,14 @@ -using System.IO; +using System; +using System.IO; using System.Text; namespace BizHawk.Common.IOExtensions { public static class IOExtensions { + public static Span GetBufferAsSpan(this MemoryStream ms) + => ms.GetBuffer().AsSpan().Slice(start: 0, length: (int) ms.Length); + public static byte[] ReadAllBytes(this Stream stream) { const int BUFF_SIZE = 4096; diff --git a/src/BizHawk.Common/checksums/CRC32Checksum.cs b/src/BizHawk.Common/checksums/CRC32Checksum.cs new file mode 100644 index 0000000000..493d46fd67 --- /dev/null +++ b/src/BizHawk.Common/checksums/CRC32Checksum.cs @@ -0,0 +1,30 @@ +using System; + +using BizHawk.Common.BufferExtensions; + +namespace BizHawk.Common +{ + /// uses custom implementation of CRC-32 (i.e. POSIX cksum) + /// + /// + /// + public static class CRC32Checksum + { + /// in bits + internal const int EXPECTED_LENGTH = 32; + + internal const string PREFIX = "CRC32"; + + public static byte[] BytesAsDigest(uint digest) + => BitConverter.GetBytes(digest); + + public static byte[] Compute(ReadOnlySpan data) + => BytesAsDigest(CRC32.Calculate(data)); + + public static string ComputeDigestHex(ReadOnlySpan data) + => Compute(data).BytesToHexString(); + + public static string ComputePrefixedHex(ReadOnlySpan data) + => $"{PREFIX}:{ComputeDigestHex(data)}"; + } +} diff --git a/src/BizHawk.Common/checksums/MD5Checksum.cs b/src/BizHawk.Common/checksums/MD5Checksum.cs new file mode 100644 index 0000000000..0bafc343cd --- /dev/null +++ b/src/BizHawk.Common/checksums/MD5Checksum.cs @@ -0,0 +1,58 @@ +using System; +using System.Diagnostics; +using System.Security.Cryptography; + +using BizHawk.Common.BufferExtensions; + +namespace BizHawk.Common +{ + /// uses implementation from BCL + /// + /// + /// + public static class MD5Checksum + { + /// in bits + internal const int EXPECTED_LENGTH = 128; + + internal const string PREFIX = "MD5"; + +#if NET5_0 + public static byte[] Compute(ReadOnlySpan data) + => MD5.HashData(data); +#else + private static MD5? _md5Impl; + + private static MD5 MD5Impl + { + get + { + if (_md5Impl == null) + { + _md5Impl = MD5.Create(); + Debug.Assert(_md5Impl.CanReuseTransform && _md5Impl.HashSize is EXPECTED_LENGTH); + } + return _md5Impl; + } + } + + public static byte[] Compute(byte[] data) + => MD5Impl.ComputeHash(data); + + public static string ComputeDigestHex(byte[] data) + => Compute(data).BytesToHexString(); + + public static string ComputePrefixedHex(byte[] data) + => $"{PREFIX}:{ComputeDigestHex(data)}"; + + public static byte[] Compute(ReadOnlySpan data) + => Compute(data.ToArray()); +#endif + + public static string ComputeDigestHex(ReadOnlySpan data) + => Compute(data).BytesToHexString(); + + public static string ComputePrefixedHex(ReadOnlySpan data) + => $"{PREFIX}:{ComputeDigestHex(data)}"; + } +} diff --git a/src/BizHawk.Common/checksums/SHA1Checksum.cs b/src/BizHawk.Common/checksums/SHA1Checksum.cs new file mode 100644 index 0000000000..4f91911aef --- /dev/null +++ b/src/BizHawk.Common/checksums/SHA1Checksum.cs @@ -0,0 +1,77 @@ +using System; +using System.Diagnostics; +using System.Security.Cryptography; + +using BizHawk.Common.BufferExtensions; + +namespace BizHawk.Common +{ + /// uses implementation from BCL + /// + /// + /// + public static class SHA1Checksum + { + /// in bits + internal const int EXPECTED_LENGTH = 160; + + internal const string PREFIX = "SHA1"; + +#if NET5_0 + public static byte[] Compute(ReadOnlySpan data) + => SHA1.HashData(data); + + public static byte[] ComputeConcat(ReadOnlySpan dataA, ReadOnlySpan dataB) + { + using var impl = IncrementalHash.CreateHash(HashAlgorithmName.SHA1); + impl.AppendData(dataA); + impl.AppendData(dataB); + return impl.GetHashAndReset(); + } +#else + private static SHA1? _sha1Impl; + + private static SHA1 SHA1Impl + { + get + { + if (_sha1Impl == null) + { + _sha1Impl = SHA1.Create(); + Debug.Assert(_sha1Impl.CanReuseTransform && _sha1Impl.HashSize is EXPECTED_LENGTH); + } + return _sha1Impl; + } + } + + public static byte[] Compute(byte[] data) + => SHA1Impl.ComputeHash(data); + + public static byte[] ComputeConcat(byte[] dataA, byte[] dataB) + { + using var impl = IncrementalHash.CreateHash(HashAlgorithmName.SHA1); + impl.AppendData(dataA); + impl.AppendData(dataB); + return impl.GetHashAndReset(); + } + + public static string ComputeDigestHex(byte[] data) + => Compute(data).BytesToHexString(); + + public static string ComputePrefixedHex(byte[] data) + => $"{PREFIX}:{ComputeDigestHex(data)}"; + + public static byte[] Compute(ReadOnlySpan data) + => Compute(data.ToArray()); + + public static byte[] ComputeConcat(ReadOnlySpan dataA, ReadOnlySpan dataB) + => ComputeConcat(dataA.ToArray(), dataB.ToArray()); +#endif + + public static string ComputeDigestHex(ReadOnlySpan data) + => Compute(data).BytesToHexString(); + + public static string ComputePrefixedHex(ReadOnlySpan data) + => $"{PREFIX}:{ComputeDigestHex(data)}"; + } +} diff --git a/src/BizHawk.Common/checksums/SHA256Checksum.cs b/src/BizHawk.Common/checksums/SHA256Checksum.cs new file mode 100644 index 0000000000..612dc6e4e1 --- /dev/null +++ b/src/BizHawk.Common/checksums/SHA256Checksum.cs @@ -0,0 +1,58 @@ +using System; +using System.Diagnostics; +using System.Security.Cryptography; + +using BizHawk.Common.BufferExtensions; + +namespace BizHawk.Common +{ + /// uses implementation from BCL + /// + /// + /// + public static class SHA256Checksum + { + /// in bits + internal const int EXPECTED_LENGTH = 256; + + internal const string PREFIX = "SHA256"; + +#if NET5_0 + public static byte[] Compute(ReadOnlySpan data) + => SHA256.HashData(data); +#else + private static SHA256? _sha256Impl; + + private static SHA256 SHA256Impl + { + get + { + if (_sha256Impl == null) + { + _sha256Impl = SHA256.Create(); + Debug.Assert(_sha256Impl.CanReuseTransform && _sha256Impl.HashSize is EXPECTED_LENGTH); + } + return _sha256Impl; + } + } + + public static byte[] Compute(byte[] data) + => SHA256Impl.ComputeHash(data); + + public static string ComputeDigestHex(byte[] data) + => Compute(data).BytesToHexString(); + + public static string ComputePrefixedHex(byte[] data) + => $"{PREFIX}:{ComputeDigestHex(data)}"; + + public static byte[] Compute(ReadOnlySpan data) + => Compute(data.ToArray()); +#endif + + public static string ComputeDigestHex(ReadOnlySpan data) + => Compute(data).BytesToHexString(); + + public static string ComputePrefixedHex(ReadOnlySpan data) + => $"{PREFIX}:{ComputeDigestHex(data)}"; + } +} diff --git a/src/BizHawk.Emulation.Common/Database/Database.cs b/src/BizHawk.Emulation.Common/Database/Database.cs index 6a8612c883..f2a6470bac 100644 --- a/src/BizHawk.Emulation.Common/Database/Database.cs +++ b/src/BizHawk.Emulation.Common/Database/Database.cs @@ -9,7 +9,6 @@ using System.Text; using System.Threading; using BizHawk.Common; -using BizHawk.Common.BufferExtensions; namespace BizHawk.Emulation.Common { @@ -191,19 +190,19 @@ namespace BizHawk.Emulation.Common { acquire.WaitOne(); - var hashCRC32 = $"{CRC32.Calculate(romData):X8}"; + var hashCRC32 = CRC32Checksum.ComputeDigestHex(romData); if (DB.TryGetValue(hashCRC32, out var cgi)) { return new GameInfo(cgi); } - var hashMD5 = romData.HashMD5(); + var hashMD5 = MD5Checksum.ComputeDigestHex(romData); if (DB.TryGetValue(hashMD5, out cgi)) { return new GameInfo(cgi); } - var hashSHA1 = romData.HashSHA1(); + var hashSHA1 = SHA1Checksum.ComputeDigestHex(romData); if (DB.TryGetValue(hashSHA1, out cgi)) { return new GameInfo(cgi); diff --git a/src/BizHawk.Emulation.Cores/Computers/Commodore64/C64.cs b/src/BizHawk.Emulation.Cores/Computers/Commodore64/C64.cs index acfa2f5f20..3bc7f764c4 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Commodore64/C64.cs +++ b/src/BizHawk.Emulation.Cores/Computers/Commodore64/C64.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge; using BizHawk.Emulation.Cores.Computers.Commodore64.Media; @@ -60,8 +60,8 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64 if (_board.CartPort.IsConnected) { - // There are no multi-cart cart games, so just hardcode .First() - RomDetails = $"{lp.Game.Name}\r\nSHA1:{_roms.First().HashSHA1()}\r\nMD5:{_roms.First().HashMD5()}\r\nMapper Impl \"{_board.CartPort.CartridgeType}\""; + var first = _roms[0]; // There are no multi-cart cart games, so just hardcode first + RomDetails = $"{lp.Game.Name}\r\n{SHA1Checksum.ComputePrefixedHex(first)}\r\n{MD5Checksum.ComputePrefixedHex(first)}\r\nMapper Impl \"{_board.CartPort.CartridgeType}\""; } SetupMemoryDomains(); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs b/src/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs index 4d9c0235b5..617f8a878b 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.Core.cs @@ -1,7 +1,7 @@ using System; +using BizHawk.Common; using BizHawk.Common.NumberExtensions; -using BizHawk.Common.BufferExtensions; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Components.M6502; @@ -220,7 +220,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 HardReset(); - RomDetails = $"{_game.Name}\r\nSHA1:{Rom.HashSHA1()}\r\nMD5:{Rom.HashMD5()}\r\nMapper Impl \"{_mapper.GetType()}\""; + RomDetails = $"{_game.Name}\r\n{SHA1Checksum.ComputePrefixedHex(Rom)}\r\n{MD5Checksum.ComputePrefixedHex(Rom)}\r\nMapper Impl \"{_mapper.GetType()}\""; // Some games (ex. 3D tic tac toe), turn off the screen for extended periods, so we need to allow for this here. if (_game.GetOptions().TryGetValue("SP_FRAME", out var spFrameStr) && spFrameStr == "true") diff --git a/src/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs b/src/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs index 307cddf265..67c85a4d86 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Atari/2600/Atari2600.cs @@ -1,7 +1,7 @@ using System; using System.Linq; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Atari.Atari2600 @@ -13,11 +13,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 { internal static class RomChecksums { - public const string CongoBongo = /*sha1:*/"3A77DB43B6583E8689435F0F14AA04B9E57BDDED"; + public const string CongoBongo = "SHA1:3A77DB43B6583E8689435F0F14AA04B9E57BDDED"; - public const string KangarooNotInGameDB = /*sha1:*/"982B8016B393A9AA7DD110295A53C4612ECF2141"; + public const string KangarooNotInGameDB = "SHA1:982B8016B393A9AA7DD110295A53C4612ECF2141"; - public const string Tapper = /*sha1:*/"E986E1818E747BEB9B33CE4DFF1CDC6B55BDB620"; + public const string Tapper = "SHA1:E986E1818E747BEB9B33CE4DFF1CDC6B55BDB620"; } [CoreConstructor(VSystemID.Raw.A26)] @@ -43,7 +43,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 game.AddOption("m", DetectMapper(rom)); } - var romHashSHA1 = Rom.HashSHA1(); + var romHashSHA1 = SHA1Checksum.ComputePrefixedHex(Rom); if (romHashSHA1 is RomChecksums.CongoBongo or RomChecksums.Tapper or RomChecksums.KangarooNotInGameDB) { game.RemoveOption("m"); @@ -82,7 +82,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600 Name = _game.Name, System = VSystemID.Raw.A26, MetaData = "m=" + _mapper.GetType().ToString().Split('.').Last(), - Hash = Rom.HashSHA1(), + Hash = SHA1Checksum.ComputeDigestHex(Rom), Region = _game.Region, Status = RomStatus.Unknown }; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.cs b/src/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.cs index 3cbf03575e..ea000557da 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.cs @@ -1,6 +1,6 @@ using System; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Components.M6502; using BizHawk.Common.NumberExtensions; @@ -14,9 +14,9 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk { internal static class RomChecksums { - public const string KaratekaPAL = "md5:5E0A1E832BBCEA6FACB832FDE23A440A"; + public const string KaratekaPAL = "MD5:5E0A1E832BBCEA6FACB832FDE23A440A"; - public const string Serpentine = "md5:9BD70C06D3386F76F8162881699A777A"; + public const string Serpentine = "MD5:9BD70C06D3386F76F8162881699A777A"; } // this register selects between 2600 and 7800 mode in the A7800 @@ -120,9 +120,8 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk // look up hash in gamedb to see what mapper to use // if none found default is zero // also check for PAL region - string hash_md5 = null; s_mapper = null; - hash_md5 = "md5:" + rom.HashMD5(0, rom.Length); + var hash_md5 = MD5Checksum.ComputePrefixedHex(rom); var gi = Database.CheckDatabase(hash_md5); diff --git a/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.cs b/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.cs index 4906952849..afd74ecb4c 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/GCE/Vectrex/VectrexHawk.cs @@ -1,6 +1,6 @@ using System; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Components.MC6809; @@ -13,7 +13,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex { internal static class RomChecksums { - public const string Minestorm = /*sha1:*/"65D07426B520DDD3115D40F255511E0FD2E20AE7"; + public const string Minestorm = "SHA1:65D07426B520DDD3115D40F255511E0FD2E20AE7"; } public byte[] RAM = new byte[0x400]; @@ -57,8 +57,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Vectrex /*var Bios =*/ _bios = comm.CoreFileProvider.GetFirmwareOrThrow(new("VEC", "Bios"), "BIOS Not Found, Cannot Load"); /*var Mine =*/ minestorm = comm.CoreFileProvider.GetFirmwareOrThrow(new("VEC", "Minestorm"), "Minestorm Not Found, Cannot Load"); - var romHashSHA1 = rom.HashSHA1(); - Console.WriteLine($"SHA1:{romHashSHA1}"); + var romHashSHA1 = SHA1Checksum.ComputePrefixedHex(rom); + Console.WriteLine(romHashSHA1); _rom = rom; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Intellivision/Cartridge.cs b/src/BizHawk.Emulation.Cores/Consoles/Intellivision/Cartridge.cs index 93ccad5e8a..a678f6bea5 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Intellivision/Cartridge.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Intellivision/Cartridge.cs @@ -1,7 +1,6 @@ using System; using BizHawk.Common; -using BizHawk.Common.BufferExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Intellivision @@ -40,7 +39,7 @@ namespace BizHawk.Emulation.Cores.Intellivision // look up hash in gamedb to see what mapper to use string s_mapper = null; - var gi = Database.CheckDatabase($"sha1:{rom.HashSHA1(16, rom.Length - 16)}"); + var gi = Database.CheckDatabase(SHA1Checksum.ComputePrefixedHex(rom.AsSpan(start: 16, length: rom.Length - 32))); if (gi != null && !gi.GetOptions().TryGetValue("board", out s_mapper)) throw new Exception("INTV gamedb entries must have a board identifier!"); _mapper = 0; int.TryParse(s_mapper, out _mapper); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.cs b/src/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.cs index a7d0659008..ee389b83b3 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Magnavox/Odyssey2/O2Hawk.cs @@ -1,6 +1,6 @@ using System; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Components.I8048; @@ -67,8 +67,8 @@ namespace BizHawk.Emulation.Cores.Consoles.O2Hawk Buffer.BlockCopy(rom, 0x100, header, 0, 0x50); - Console.WriteLine("MD5: " + rom.HashMD5(0, rom.Length)); - Console.WriteLine("SHA1: " + rom.HashSHA1(0, rom.Length)); + Console.WriteLine(MD5Checksum.ComputePrefixedHex(rom)); + Console.WriteLine(SHA1Checksum.ComputePrefixedHex(rom)); _rom = rom; if (game["XROM"]) { is_XROM = true; } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.cs index 76ecc43dbc..fe2490585d 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/BsnesCore.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Xml; using System.IO; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Components.W65816; @@ -48,7 +48,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES ? CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("SNES", "Rom_SGB2"), "SGB2 Rom is required for SGB2 emulation.") : CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("SNES", "Rom_SGB"), "SGB1 Rom is required for SGB1 emulation."); - game.FirmwareHash = sgbRomData.HashSHA1(); + game.FirmwareHash = SHA1Checksum.ComputeDigestHex(sgbRomData); } BsnesApi.SnesCallbacks callbacks = new() diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs index e1ad0b2a48..87bcb30ddf 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBHawk/GBHawk.cs @@ -1,6 +1,6 @@ using System; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Components.LR35902; @@ -26,27 +26,27 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk { internal static class RomChecksums { - public const string BombermanCollection = /*sha1:*/"385F8FAFA53A83F8F65E1E619FE124BBF7DB4A98"; + public const string BombermanCollection = "SHA1:385F8FAFA53A83F8F65E1E619FE124BBF7DB4A98"; - public const string BombermanSelectionKORNotInGameDB = /*sha1:*/"52451464A9F4DD5FAEFE4594954CBCE03BFF0D05"; + public const string BombermanSelectionKORNotInGameDB = "SHA1:52451464A9F4DD5FAEFE4594954CBCE03BFF0D05"; - public const string MortalKombatIAndIIUSAEU = /*sha1:*/"E337489255B33367CE26194FC4038346D3388BD9"; + public const string MortalKombatIAndIIUSAEU = "SHA1:E337489255B33367CE26194FC4038346D3388BD9"; - public const string PirateRockMan8 = /*md5:*/"CAE0998A899DF2EE6ABA8E7695C2A096"; + public const string PirateRockMan8 = "MD5:CAE0998A899DF2EE6ABA8E7695C2A096"; - public const string PirateSachen1 = /*md5:*/"D3C1924D847BC5D125BF54C2076BE27A"; + public const string PirateSachen1 = "MD5:D3C1924D847BC5D125BF54C2076BE27A"; - public const string UnknownRomA = /*md5:*/"97122B9B183AAB4079C8D36A4CE6E9C1"; + public const string UnknownRomA = "MD5:97122B9B183AAB4079C8D36A4CE6E9C1"; - public const string WisdomTreeExodus = /*sha1:*/"685D5A47A1FC386D7B451C8B2733E654B7779B71"; + public const string WisdomTreeExodus = "SHA1:685D5A47A1FC386D7B451C8B2733E654B7779B71"; - public const string WisdomTreeJoshua = /*sha1:*/"019B4B0E76336E2613AE6E8B415B5C65F6D465A5"; + public const string WisdomTreeJoshua = "SHA1:019B4B0E76336E2613AE6E8B415B5C65F6D465A5"; - public const string WisdomTreeKJVBible = /*sha1:*/"6362FDE9DCB08242A64F2FBEA33DE93D1776A6E0"; + public const string WisdomTreeKJVBible = "SHA1:6362FDE9DCB08242A64F2FBEA33DE93D1776A6E0"; - public const string WisdomTreeNIVBible = /*sha1:*/"136CF97A8C3560EC9DB3D8F354D91B7DE27E0743"; + public const string WisdomTreeNIVBible = "SHA1:136CF97A8C3560EC9DB3D8F354D91B7DE27E0743"; - public const string WisdomTreeSpiritualWarfare = /*sha1:*/"6E6AE5DBD8FF8B8F41B8411EF119E96E4ECF763F"; + public const string WisdomTreeSpiritualWarfare = "SHA1:6E6AE5DBD8FF8B8F41B8411EF119E96E4ECF763F"; } // this register controls whether or not the GB BIOS is mapped into memory @@ -186,10 +186,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBHawk is_GB_in_GBC = true; // for movie files } - var romHashMD5 = rom.HashMD5(); - Console.WriteLine($"MD5: {romHashMD5}"); - var romHashSHA1 = rom.HashSHA1(); - Console.WriteLine($"SHA1: {romHashSHA1}"); + var romHashMD5 = MD5Checksum.ComputePrefixedHex(rom); + Console.WriteLine(romHashMD5); + var romHashSHA1 = SHA1Checksum.ComputePrefixedHex(rom); + Console.WriteLine(romHashSHA1); _rom = rom; var mppr = Setup_Mapper(romHashMD5, romHashSHA1); if (cart_RAM != null) { cart_RAM_vbls = new byte[cart_RAM.Length]; } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs index 1672309a17..81ba126db8 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using BizHawk.Common; -using BizHawk.Common.BufferExtensions; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Consoles.Nintendo.Gameboy; @@ -137,7 +136,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy InitMemoryDomains(); - RomDetails = $"{game.Name}\r\nSHA1:{file.HashSHA1()}\r\nMD5:{file.HashMD5()}\r\n"; + RomDetails = $"{game.Name}\r\n{SHA1Checksum.ComputePrefixedHex(file)}\r\n{MD5Checksum.ComputePrefixedHex(file)}\r\n"; byte[] buff = new byte[32]; LibGambatte.gambatte_romtitle(GambatteState, buff); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSFirmware.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSFirmware.cs index a8e492a671..903cb024bd 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSFirmware.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSFirmware.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Common; namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS @@ -192,7 +192,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS byte[] DecryptedFirmware = new byte[decrypedfwlen]; Marshal.Copy(decryptedfw, DecryptedFirmware, 0, decrypedfwlen); FreeDecryptedFirmware(decryptedfw); - var hash = BufferExtensions.HashSHA1(DecryptedFirmware, 0, decrypedfwlen); + var hash = SHA1Checksum.ComputeDigestHex(DecryptedFirmware); if (hash != goodhashes[0] && hash != goodhashes[1] && hash != goodhashes[2]) { comm.ShowMessage("Potentially bad firmware dump! Decrypted hash " + hash + " does not match known good dumps."); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/BootGodDB.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/BootGodDB.cs index d728ad1ae9..6fd6db068b 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/BootGodDB.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/BootGodDB.cs @@ -135,7 +135,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES { currCart = new CartInfo(); currCart.System = xmlReader.GetAttribute("system"); - currCart.Sha1 = "sha1:" + xmlReader.GetAttribute("sha1"); + currCart.Sha1 = $"SHA1:{xmlReader.GetAttribute("sha1")}"; currCart.Name = currName; state = 2; } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs index a94988903d..ae4a07c315 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.Core.cs @@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES public const string DancingBlocks = /*sha1:*/"68ABE1E49C9E9CCEA978A48232432C252E5912C0"; - public const string SeicrossRev2 = "sha1:4C9C05FAD6F6F33A92A27C2EDC1E7DE12D7F216D"; // yes this is meant to include the prefix + public const string SeicrossRev2 = "SHA1:4C9C05FAD6F6F33A92A27C2EDC1E7DE12D7F216D"; // yes this is meant to include the prefix public const string SilvaSaga = /*sha1:*/"00C50062A2DECE99580063777590F26A253AAB6B"; @@ -258,23 +258,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES // some boards cannot have specific values in RAM upon initialization // Let's hard code those cases here // these will be defined through the gameDB exclusively for now. - if (cart.GameInfo != null) + var hash = cart.GameInfo?.Hash; // SHA1 or MD5 (see NES.IdentifyFromGameDB) + if (hash is null) { - if (cart.GameInfo.Hash is RomChecksums.CamericaGolden5 or RomChecksums.CamericaGolden5Overdump or RomChecksums.CamericaPegasus4in1) + // short-circuit + } + else if (hash is RomChecksums.CamericaGolden5 or RomChecksums.CamericaGolden5Overdump or RomChecksums.CamericaPegasus4in1) + { + ram[0x701] = 0xFF; + } + else if (hash == RomChecksums.DancingBlocks) + { + ram[0xEC] = 0; + ram[0xED] = 0; + } + else if (hash == RomChecksums.SilvaSaga || hash == RomChecksums.Fam_Jump_II) + { + for (int i = 0; i < Board.Wram.Length; i++) { - ram[0x701] = 0xFF; - } - else if (cart.GameInfo.Hash == RomChecksums.DancingBlocks) - { - ram[0xEC] = 0; - ram[0xED] = 0; - } - else if (cart.GameInfo.Hash == RomChecksums.SilvaSaga || cart.GameInfo.Hash == RomChecksums.Fam_Jump_II) - { - for (int i = 0; i < Board.Wram.Length; i++) - { - Board.Wram[i] = 0xFF; - } + Board.Wram[i] = 0xFF; } } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs index 2734285b0d..ec1fe9bb03 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs @@ -3,7 +3,7 @@ using System.Linq; using System.IO; using System.Collections.Generic; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Common; //TODO - redo all timekeeping in terms of master clock @@ -417,11 +417,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES // we don't have an ines header, check if the game hash is in the game db exists = false; Console.WriteLine("headerless ROM, using Game DB"); - hash_md5 = "md5:" + file.HashMD5(0, file.Length); - hash_sha1 = "sha1:" + file.HashSHA1(0, file.Length); - if (hash_md5 != null) choice = IdentifyFromGameDB(hash_md5); - if (choice == null) - choice = IdentifyFromGameDB(hash_sha1); + hash_md5 = MD5Checksum.ComputePrefixedHex(file); + hash_sha1 = SHA1Checksum.ComputePrefixedHex(file); + choice = IdentifyFromGameDB(hash_md5) ?? IdentifyFromGameDB(hash_sha1); if (choice==null) { hash_sha1_several.Add(hash_sha1); @@ -443,9 +441,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES { //now that we know we have an iNES header, we can try to ignore it. - hash_sha1 = "sha1:" + file.HashSHA1(16, file.Length - 16); + var trimmed = file.AsSpan(start: 16, length: file.Length - 32); + hash_sha1 = SHA1Checksum.ComputePrefixedHex(trimmed); hash_sha1_several.Add(hash_sha1); - hash_md5 = "md5:" + file.HashMD5(16, file.Length - 16); + hash_md5 = MD5Checksum.ComputePrefixedHex(trimmed); LoadWriteLine("Found iNES header:"); LoadWriteLine(iNesHeaderInfo.ToString()); @@ -485,10 +484,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES } msTemp.Flush(); var bytes = msTemp.ToArray(); - var hash = "sha1:" + bytes.HashSHA1(0, bytes.Length); + var hash = SHA1Checksum.ComputePrefixedHex(bytes); LoadWriteLine(" PRG (8KB) + CHR hash: {0}", hash); hash_sha1_several.Add(hash); - hash = "md5:" + bytes.HashMD5(0, bytes.Length); + hash = MD5Checksum.ComputePrefixedHex(bytes); LoadWriteLine(" PRG (8KB) + CHR hash: {0}", hash); } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Unif.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Unif.cs index 35c8f608ad..a4e14129d5 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Unif.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Unif.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.IO; +using BizHawk.Common; using BizHawk.Common.BufferExtensions; using BizHawk.Common.IOExtensions; @@ -95,16 +96,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES Cart.WramBattery = true; } - // is there any way using System.Security.Cryptography.SHA1 to compute the hash of - // prg concatenated with chr? i couldn't figure it out, so this implementation is dumb - { - var ms = new MemoryStream(); - ms.Write(Prg, 0, Prg.Length); - ms.Write(Chr, 0, Chr.Length); - ms.Close(); - var all = ms.ToArray(); - Cart.Sha1 = "sha1:" + all.HashSHA1(0, all.Length); - } + Cart.Sha1 = SHA1Checksum.ComputeConcat(Prg, Chr).BytesToHexString(); // other code will expect this if (Chr.Length == 0) diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs index 423b9f62d3..ba3b981ac3 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.cs @@ -9,7 +9,6 @@ using BizHawk.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Nintendo.NES; using BizHawk.BizInvoke; -using BizHawk.Common.BufferExtensions; namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES { @@ -245,7 +244,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES for (int i = 0; i < chrrom.Size; i++) ms.WriteByte(chrrom.PeekByte(i)); - string sha1 = ms.ToArray().HashSHA1(); + var sha1 = SHA1Checksum.ComputeDigestHex(ms.ToArray()); Console.WriteLine("Hash for BootGod: {0}", sha1); // Bail out on ROM's known to not be playable by this core @@ -300,7 +299,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES // we need to do this from the raw file since QuickNES hasn't had time to process it yet. private byte[] FixInesHeader(byte[] file) { - string sha1 = BufferExtensions.HashSHA1(file); + var sha1 = SHA1Checksum.ComputeDigestHex(file); bool didSomething = false; Console.WriteLine(sha1); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs index 71beb04d91..df2e2f7b94 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -3,7 +3,7 @@ using System.Linq; using System.Xml; using System.IO; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Components.W65816; @@ -53,7 +53,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES } sgbRomData = CoreComm.CoreFileProvider.GetFirmwareOrThrow(new("SNES", "Rom_SGB"), "SGB Rom is required for SGB emulation."); - game.FirmwareHash = sgbRomData.HashSHA1(); + game.FirmwareHash = SHA1Checksum.ComputeDigestHex(sgbRomData); } _settings = (SnesSettings)settings ?? new SnesSettings(); diff --git a/src/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs b/src/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs index 252468b125..4b93533402 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores.Components; using BizHawk.Emulation.Cores.Components.H6280; @@ -68,7 +68,7 @@ namespace BizHawk.Emulation.Cores.PCEngine throw new Exception(); } - lp.Game.FirmwareHash = rom.HashSHA1(); + lp.Game.FirmwareHash = SHA1Checksum.ComputeDigestHex(rom); Init(lp.Game, rom); diff --git a/src/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs b/src/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs index 31205030fa..6d31d36a60 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs @@ -66,7 +66,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX var sw = new StringWriter(); foreach (var d in lp.Discs) { - var discHash = new DiscHasher(d.DiscData).Calculate_PSX_BizIDHash().ToString("X8"); + var discHash = new DiscHasher(d.DiscData).Calculate_PSX_BizIDHash(); sw.WriteLine(Path.GetFileName(d.DiscName)); sw.WriteLine(DiscHashWarningText(Database.CheckDatabase(discHash), discHash)); sw.WriteLine("-------------------------"); diff --git a/src/BizHawk.Emulation.DiscSystem/DiscHasher.cs b/src/BizHawk.Emulation.DiscSystem/DiscHasher.cs index 8a108d40ed..b0657d252f 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscHasher.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscHasher.cs @@ -17,7 +17,7 @@ namespace BizHawk.Emulation.DiscSystem /// /// calculates the hash for quick PSX Disc identification /// - public uint Calculate_PSX_BizIDHash() + public string Calculate_PSX_BizIDHash() { //notes about the hash: //"Arc the Lad II (J) 1.0 and 1.1 conflict up to 25 sectors (so use 26) @@ -54,7 +54,7 @@ namespace BizHawk.Emulation.DiscSystem crc.Add(buffer2352); } - return crc.Result; + return CRC32Checksum.BytesAsDigest(crc.Result).BytesToHexString(); } /// @@ -97,7 +97,7 @@ namespace BizHawk.Emulation.DiscSystem for (int s = 0; s < 512 && s < lba_len; s++) dsr.ReadLBA_2352(track.LBA + s, buffer, s * 2352); - return buffer.HashMD5(0, lba_len * 2352); + return MD5Checksum.ComputeDigestHex(buffer.AsSpan(start: 0, length: lba_len * 2352)); } return "no data track found"; } diff --git a/src/BizHawk.Tests/Client.Common/dearchive/DearchivalTests.cs b/src/BizHawk.Tests/Client.Common/dearchive/DearchivalTests.cs index fa0596c218..b2ce159d8d 100644 --- a/src/BizHawk.Tests/Client.Common/dearchive/DearchivalTests.cs +++ b/src/BizHawk.Tests/Client.Common/dearchive/DearchivalTests.cs @@ -3,7 +3,7 @@ using System.IO; using System.Linq; using BizHawk.Client.Common; -using BizHawk.Common.BufferExtensions; +using BizHawk.Common; using BizHawk.Common.IOExtensions; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -29,7 +29,7 @@ namespace BizHawk.Tests.Client.Common.Dearchive private byte[] Rom => _rom.Value; [TestMethod] - public void SanityCheck() => Assert.AreEqual("70DCA8E791878BDD32426391E4233EA52B47CDD1", Rom.HashSHA1()); + public void SanityCheck() => Assert.AreEqual("SHA1:70DCA8E791878BDD32426391E4233EA52B47CDD1", SHA1Checksum.ComputePrefixedHex(Rom)); [TestMethod] public void TestSharpCompress()