Unify checksum helper methods

This commit is contained in:
YoshiRulz 2021-11-12 18:20:09 +10:00
parent 73af92b579
commit e38726db50
No known key found for this signature in database
GPG Key ID: C4DE31C245353FB7
36 changed files with 337 additions and 180 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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<string, byte[]>(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)
{

View File

@ -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<string, RealFirmwareFile> _dict = new();
private SHA1? _sha1 = SHA1.Create();
public IReadOnlyDictionary<string, RealFirmwareFile> 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<string, string> 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<DirectoryInfo>(new[] { new DirectoryInfo(pathEntries.AbsolutePathFor(pathEntries.FirmwaresPathFragment, null)) });

View File

@ -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");

View File

@ -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)
{

View File

@ -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))
{

View File

@ -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')

View File

@ -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<byte> 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;

View File

@ -0,0 +1,30 @@
using System;
using BizHawk.Common.BufferExtensions;
namespace BizHawk.Common
{
/// <summary>uses <see cref="CRC32">custom implementation</see> of CRC-32 (i.e. POSIX cksum)</summary>
/// <seealso cref="MD5Checksum"/>
/// <seealso cref="SHA1Checksum"/>
/// <seealso cref="SHA256Checksum"/>
public static class CRC32Checksum
{
/// <remarks>in bits</remarks>
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<byte> data)
=> BytesAsDigest(CRC32.Calculate(data));
public static string ComputeDigestHex(ReadOnlySpan<byte> data)
=> Compute(data).BytesToHexString();
public static string ComputePrefixedHex(ReadOnlySpan<byte> data)
=> $"{PREFIX}:{ComputeDigestHex(data)}";
}
}

View File

@ -0,0 +1,58 @@
using System;
using System.Diagnostics;
using System.Security.Cryptography;
using BizHawk.Common.BufferExtensions;
namespace BizHawk.Common
{
/// <summary>uses <see cref="MD5"/> implementation from BCL</summary>
/// <seealso cref="CRC32Checksum"/>
/// <seealso cref="SHA1Checksum"/>
/// <seealso cref="SHA256Checksum"/>
public static class MD5Checksum
{
/// <remarks>in bits</remarks>
internal const int EXPECTED_LENGTH = 128;
internal const string PREFIX = "MD5";
#if NET5_0
public static byte[] Compute(ReadOnlySpan<byte> 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<byte> data)
=> Compute(data.ToArray());
#endif
public static string ComputeDigestHex(ReadOnlySpan<byte> data)
=> Compute(data).BytesToHexString();
public static string ComputePrefixedHex(ReadOnlySpan<byte> data)
=> $"{PREFIX}:{ComputeDigestHex(data)}";
}
}

View File

@ -0,0 +1,77 @@
using System;
using System.Diagnostics;
using System.Security.Cryptography;
using BizHawk.Common.BufferExtensions;
namespace BizHawk.Common
{
/// <summary>uses <see cref="SHA1"/> implementation from BCL</summary>
/// <seealso cref="CRC32Checksum"/>
/// <seealso cref="MD5Checksum"/>
/// <seealso cref="SHA256Checksum"/>
public static class SHA1Checksum
{
/// <remarks>in bits</remarks>
internal const int EXPECTED_LENGTH = 160;
internal const string PREFIX = "SHA1";
#if NET5_0
public static byte[] Compute(ReadOnlySpan<byte> data)
=> SHA1.HashData(data);
public static byte[] ComputeConcat(ReadOnlySpan<byte> dataA, ReadOnlySpan<byte> 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<byte> data)
=> Compute(data.ToArray());
public static byte[] ComputeConcat(ReadOnlySpan<byte> dataA, ReadOnlySpan<byte> dataB)
=> ComputeConcat(dataA.ToArray(), dataB.ToArray());
#endif
public static string ComputeDigestHex(ReadOnlySpan<byte> data)
=> Compute(data).BytesToHexString();
public static string ComputePrefixedHex(ReadOnlySpan<byte> data)
=> $"{PREFIX}:{ComputeDigestHex(data)}";
}
}

View File

@ -0,0 +1,58 @@
using System;
using System.Diagnostics;
using System.Security.Cryptography;
using BizHawk.Common.BufferExtensions;
namespace BizHawk.Common
{
/// <summary>uses <see cref="SHA256"/> implementation from BCL</summary>
/// <seealso cref="CRC32Checksum"/>
/// <seealso cref="MD5Checksum"/>
/// <seealso cref="SHA1Checksum"/>
public static class SHA256Checksum
{
/// <remarks>in bits</remarks>
internal const int EXPECTED_LENGTH = 256;
internal const string PREFIX = "SHA256";
#if NET5_0
public static byte[] Compute(ReadOnlySpan<byte> 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<byte> data)
=> Compute(data.ToArray());
#endif
public static string ComputeDigestHex(ReadOnlySpan<byte> data)
=> Compute(data).BytesToHexString();
public static string ComputePrefixedHex(ReadOnlySpan<byte> data)
=> $"{PREFIX}:{ComputeDigestHex(data)}";
}
}

View File

@ -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);

View File

@ -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();

View File

@ -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")

View File

@ -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
};

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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; }

View File

@ -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()

View File

@ -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]; }

View File

@ -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);

View File

@ -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.");

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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)

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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("-------------------------");

View File

@ -17,7 +17,7 @@ namespace BizHawk.Emulation.DiscSystem
/// <summary>
/// calculates the hash for quick PSX Disc identification
/// </summary>
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();
}
/// <summary>
@ -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";
}

View File

@ -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()