diff --git a/SabreTools.Library/FileTypes/BaseFile.cs b/SabreTools.Library/FileTypes/BaseFile.cs
index f3e01481..bcd83ba2 100644
--- a/SabreTools.Library/FileTypes/BaseFile.cs
+++ b/SabreTools.Library/FileTypes/BaseFile.cs
@@ -21,6 +21,7 @@ namespace SabreTools.Library.FileTypes
public long? Size { get; set; }
public byte[] CRC { get; set; }
public byte[] MD5 { get; set; }
+ public byte[] RIPEMD160 { get; set; }
public byte[] SHA1 { get; set; }
public byte[] SHA256 { get; set; }
public byte[] SHA384 { get; set; }
@@ -49,13 +50,13 @@ namespace SabreTools.Library.FileTypes
if (getHashes)
{
BaseFile temp = Utilities.GetFileInfo(this.Filename);
-
if (temp != null)
{
this.Parent = temp.Parent;
this.Date = temp.Date;
this.CRC = temp.CRC;
this.MD5 = temp.MD5;
+ this.RIPEMD160 = temp.RIPEMD160;
this.SHA1 = temp.SHA1;
this.SHA256 = temp.SHA256;
this.SHA384 = temp.SHA384;
@@ -77,13 +78,13 @@ namespace SabreTools.Library.FileTypes
if (getHashes)
{
BaseFile temp = Utilities.GetStreamInfo(stream, stream.Length);
-
if(temp != null)
{
this.Parent = temp.Parent;
this.Date = temp.Date;
this.CRC = temp.CRC;
this.MD5 = temp.MD5;
+ this.RIPEMD160 = temp.RIPEMD160;
this.SHA1 = temp.SHA1;
this.SHA256 = temp.SHA256;
this.SHA384 = temp.SHA384;
@@ -93,31 +94,6 @@ namespace SabreTools.Library.FileTypes
}
- ///
- /// Create a new BaseFile from the given metadata
- ///
- /// Name of the file to use
- /// Parent folder or archive
- /// File date
- /// CRC hash as a byte array
- /// MD5 hash as a byte array
- /// SHA-1 hash as a byte array
- /// SHA-256 hash as a byte array
- /// SHA-384 hash as a byte array
- /// SHA-512 hash as a byte array
- public BaseFile(string filename, string parent, string date, byte[] crc, byte[] md5, byte[] sha1, byte[] sha256, byte[] sha384, byte[] sha512)
- {
- this.Filename = filename;
- this.Parent = parent;
- this.Date = date;
- this.CRC = crc;
- this.MD5 = md5;
- this.SHA1 = sha1;
- this.SHA256 = sha256;
- this.SHA384 = sha384;
- this.SHA512 = sha512;
- }
-
#endregion
}
}
diff --git a/SabreTools.Library/FileTypes/CHDFile.cs b/SabreTools.Library/FileTypes/CHDFile.cs
index a08ec7e9..7f38515c 100644
--- a/SabreTools.Library/FileTypes/CHDFile.cs
+++ b/SabreTools.Library/FileTypes/CHDFile.cs
@@ -158,21 +158,15 @@ namespace SabreTools.Library.FileTypes
m_br = new BinaryReader(chdstream);
_headerVersion = ValidateHeaderVersion();
-
if (_headerVersion != null)
{
byte[] hash = GetHashFromHeader();
-
if (hash != null)
{
if (hash.Length == Constants.MD5Length)
- {
this.MD5 = hash;
- }
else if (hash.Length == Constants.SHA1Length)
- {
this.SHA1 = hash;
- }
}
}
}
@@ -197,9 +191,7 @@ namespace SabreTools.Library.FileTypes
// If no signature could be read, return null
if (m_signature == null || m_signature.Length == 0)
- {
return null;
- }
if (!m_signature.StartsWith(Constants.CHDSignature, exact: true))
{
diff --git a/SabreTools.Library/FileTypes/GZipArchive.cs b/SabreTools.Library/FileTypes/GZipArchive.cs
index 732a4033..e8c94289 100644
--- a/SabreTools.Library/FileTypes/GZipArchive.cs
+++ b/SabreTools.Library/FileTypes/GZipArchive.cs
@@ -243,7 +243,7 @@ namespace SabreTools.Library.FileTypes
var gz = new gZip();
ZipReturn ret = gz.ZipFileOpen(this.Filename);
ret = gz.ZipFileOpenReadStream(0, out Stream gzstream, out ulong streamSize);
- BaseFile gzipEntryRom = Utilities.GetStreamInfo(gzstream, gzstream.Length, omitFromScan: omitFromScan);
+ BaseFile gzipEntryRom = Utilities.GetStreamInfo(gzstream, gzstream.Length, omitFromScan);
gzipEntryRom.Filename = gz.Filename(0);
gzipEntryRom.Parent = gamename;
gzipEntryRom.Date = (date && gz.TimeStamp > 0 ? gz.TimeStamp.ToString() : null);
diff --git a/SabreTools.Library/FileTypes/RarArchive.cs b/SabreTools.Library/FileTypes/RarArchive.cs
index d84debea..bdac57c7 100644
--- a/SabreTools.Library/FileTypes/RarArchive.cs
+++ b/SabreTools.Library/FileTypes/RarArchive.cs
@@ -215,7 +215,7 @@ namespace SabreTools.Library.FileTypes
else
{
Stream entryStream = entry.OpenEntryStream();
- BaseFile rarEntryRom = Utilities.GetStreamInfo(entryStream, entry.Size, omitFromScan: omitFromScan);
+ BaseFile rarEntryRom = Utilities.GetStreamInfo(entryStream, entry.Size, omitFromScan);
rarEntryRom.Filename = entry.Key;
rarEntryRom.Parent = gamename;
rarEntryRom.Date = entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss");
diff --git a/SabreTools.Library/FileTypes/SevenZipArchive.cs b/SabreTools.Library/FileTypes/SevenZipArchive.cs
index 1d0c17d7..5ff66cac 100644
--- a/SabreTools.Library/FileTypes/SevenZipArchive.cs
+++ b/SabreTools.Library/FileTypes/SevenZipArchive.cs
@@ -328,7 +328,7 @@ namespace SabreTools.Library.FileTypes
// Otherwise, use the stream directly
else
{
- BaseFile zipEntryRom = Utilities.GetStreamInfo(readStream, (long)zf.UncompressedSize(i), omitFromScan: omitFromScan, keepReadOpen: true);
+ BaseFile zipEntryRom = Utilities.GetStreamInfo(readStream, (long)zf.UncompressedSize(i), omitFromScan, true);
zipEntryRom.Filename = zf.Filename(i);
zipEntryRom.Parent = gamename;
found.Add(zipEntryRom);
diff --git a/SabreTools.Library/FileTypes/TapeArchive.cs b/SabreTools.Library/FileTypes/TapeArchive.cs
index e5e575ee..25a009cb 100644
--- a/SabreTools.Library/FileTypes/TapeArchive.cs
+++ b/SabreTools.Library/FileTypes/TapeArchive.cs
@@ -218,7 +218,7 @@ namespace SabreTools.Library.FileTypes
else
{
Stream entryStream = entry.OpenEntryStream();
- BaseFile tarEntryRom = Utilities.GetStreamInfo(entryStream, entry.Size, omitFromScan: omitFromScan);
+ BaseFile tarEntryRom = Utilities.GetStreamInfo(entryStream, entry.Size, omitFromScan);
tarEntryRom.Filename = entry.Key;
tarEntryRom.Parent = gamename;
tarEntryRom.Date = entry.LastModifiedTime?.ToString("yyyy/MM/dd hh:mm:ss");
diff --git a/SabreTools.Library/FileTypes/ZipArchive.cs b/SabreTools.Library/FileTypes/ZipArchive.cs
index 9754704e..e5e951e0 100644
--- a/SabreTools.Library/FileTypes/ZipArchive.cs
+++ b/SabreTools.Library/FileTypes/ZipArchive.cs
@@ -328,7 +328,7 @@ namespace SabreTools.Library.FileTypes
// Otherwise, use the stream directly
else
{
- BaseFile zipEntryRom = Utilities.GetStreamInfo(readStream, (long)zf.UncompressedSize(i), omitFromScan: omitFromScan, keepReadOpen: true);
+ BaseFile zipEntryRom = Utilities.GetStreamInfo(readStream, (long)zf.UncompressedSize(i), omitFromScan, true);
zipEntryRom.Filename = zf.Filename(i);
zipEntryRom.Parent = gamename;
string convertedDate = zf.LastModified(i).ToString("yyyy/MM/dd hh:mm:ss");
diff --git a/SabreTools.Library/README.1ST b/SabreTools.Library/README.1ST
index 4c476699..2defe6b1 100644
--- a/SabreTools.Library/README.1ST
+++ b/SabreTools.Library/README.1ST
@@ -176,6 +176,10 @@ Options:
This allows the user to skip calculating the MD5 for each of the
files which will speed up the creation of the DAT.
+ -nr160, --skip-ripemd160 Don't include RIPEMD160 in output
+ This allows the user to skip calculating the RIPEMD160 for each of
+ the files which will speed up the creation of the DAT.
+
-ns, --skip-sha1 Don't include SHA-1 in output
This allows the user to skip calculating the SHA-1 for each of the
files which will speed up the creation of the DAT.
@@ -222,6 +226,7 @@ Options:
msx, openmsx - openMSX Software List
ol, offlinelist - OfflineList XML
rc, romcenter - RomCenter
+ ripemd160 - RIPEMD160
sd, sabredat - SabreDat XML
sfv - SFV
sha1 - SHA1
@@ -417,6 +422,18 @@ Options:
the user can specify an exact match or full C#-style regex for
pattern matching. Multiple instances of this flag are allowed.
+ -ripemd160=, --ripemd160= Filter by RIPEMD160 hash
+ Include only items with this RIPEMD160 hash in the output.
+ Additionally, the user can specify an exact match or full C#-style
+ regex for pattern matching. Multiple instances of this flag are
+ allowed.
+
+ -nripemd160=, --not-ripemd160= Filter by not RIPEMD160 hash
+ Include only items without this RIPEMD160 hash in the output.
+ Additionally, the user can specify an exact match or full C#-style
+ regex for pattern matching. Multiple instances of this flag are
+ allowed.
+
-sha1=, --sha1= Filter by SHA-1 hash
Include only items with this SHA-1 hash in the output. Additionally,
the user can specify an exact match or full C#-style regex for
@@ -751,6 +768,7 @@ Options:
msx, openmsx - openMSX Software List
ol, offlinelist - OfflineList XML
rc, romcenter - RomCenter
+ ripemd160 - RIPEMD160
sd, sabredat - SabreDat XML
sfv - SFV
sha1 - SHA1
@@ -924,6 +942,7 @@ Options:
msx, openmsx - openMSX Software List
ol, offlinelist - OfflineList XML
rc, romcenter - RomCenter
+ ripemd160 - RIPEMD160
sd, sabredat - SabreDat XML
sfv - SFV
sha1 - SHA1
@@ -949,6 +968,7 @@ Options:
- %publisher% - Replaced with game Publisher
- %crc% - Replaced with the CRC
- %md5% - Replaced with the MD5
+ - %ripemd160% - Replaced with the RIPEMD160
- %sha1% - Replaced with the SHA-1
- %sha256% - Replaced with the SHA-256
- %sha384% - Replaced with the SHA-384
@@ -1084,6 +1104,10 @@ Options:
By default, all available hashes will be written out to the DAT. This
will remove all MD5 hashes from the output file(s).
+ -rripemd160, --remove-ripemd160 Remove RIPEMD160 hashes from the output
+ By default, all available hashes will be written out to the DAT. This
+ will remove all RIPEMD160 hashes from the output file(s).
+
-rsha1, --remove-sha1 Remove SHA-1 hashes from the output
By default, all available hashes will be written out to the DAT. This
will remove all SHA-1 hashes from the output file(s).
@@ -1371,6 +1395,18 @@ Options:
the user can specify an exact match or full C#-style regex for
pattern matching. Multiple instances of this flag are allowed.
+ -ripemd160=, --ripemd160= Filter by RIPEMD160 hash
+ Include only items with this RIPEMD160 hash in the output.
+ Additionally, the user can specify an exact match or full C#-style
+ regex for pattern matching. Multiple instances of this flag are
+ allowed.
+
+ -nripemd160=, --not-ripemd160= Filter by not RIPEMD160 hash
+ Include only items without this RIPEMD160 hash in the output.
+ Additionally, the user can specify an exact match or full C#-style
+ regex for pattern matching. Multiple instances of this flag are
+ allowed.
+
-sha1=, --sha1= Filter by SHA-1 hash
Include only items with this SHA-1 hash in the output. Additionally,
the user can specify an exact match or full C#-style regex for
@@ -1616,6 +1652,18 @@ Options:
the user can specify an exact match or full C#-style regex for
pattern matching. Multiple instances of this flag are allowed.
+ -ripemd160=, --ripemd160= Filter by RIPEMD160 hash
+ Include only items with this RIPEMD160 hash in the output.
+ Additionally, the user can specify an exact match or full C#-style
+ regex for pattern matching. Multiple instances of this flag are
+ allowed.
+
+ -nripemd160=, --not-ripemd160= Filter by not RIPEMD160 hash
+ Include only items without this RIPEMD160 hash in the output.
+ Additionally, the user can specify an exact match or full C#-style
+ regex for pattern matching. Multiple instances of this flag are
+ allowed.
+
-sha1=, --sha1= Filter by SHA-1 hash
Include only items with this SHA-1 hash in the output. Additionally,
the user can specify an exact match or full C#-style regex for
@@ -1827,6 +1875,7 @@ This section contains remappings from old flag names to new ones for the purpose
-ool, --output-ol -> -ot=ol, --output-type=offlinelist
-ool, --output-offlinelist -> -ot=ol, --output-type=offlinelist
-or, --output-rc -> -ot=rc, --output-type=romcenter
+-oripemd160, --output-ripemd160 -> -ot=ripemd160, --output-type=ripemd160
-or, --output-romcenter -> -ot=rc, --output-type=romcenter
-os, --output-sd -> -ot=sd, --output-type=sabredat
-os, --output-sabredat -> -ot=sd, --output-type=sabredat
diff --git a/SabreTools.Library/Reports/Html.cs b/SabreTools.Library/Reports/Html.cs
index 09cbc4c9..f9cca4e0 100644
--- a/SabreTools.Library/Reports/Html.cs
+++ b/SabreTools.Library/Reports/Html.cs
@@ -60,6 +60,7 @@ namespace SabreTools.Library.Reports
+ "| " + _datFile.DiskCount + " | "
+ "" + _datFile.CRCCount + " | "
+ "" + _datFile.MD5Count + " | "
+ + "" + _datFile.RIPEMD160Count + " | "
+ "" + _datFile.SHA1Count + " | "
+ "" + _datFile.SHA256Count + " | "
+ (_baddumpCol ? "" + _datFile.BaddumpCount + " | " : "")
diff --git a/SabreTools.Library/Reports/SeparatedValue.cs b/SabreTools.Library/Reports/SeparatedValue.cs
index ef1e74f7..f310cd4f 100644
--- a/SabreTools.Library/Reports/SeparatedValue.cs
+++ b/SabreTools.Library/Reports/SeparatedValue.cs
@@ -60,6 +60,7 @@ namespace SabreTools.Library.Reports
+ "\"" + _datFile.DiskCount + "\"{0}"
+ "\"" + _datFile.CRCCount + "\"{0}"
+ "\"" + _datFile.MD5Count + "\"{0}"
+ + "\"" + _datFile.RIPEMD160Count + "\"{0}"
+ "\"" + _datFile.SHA1Count + "\"{0}"
+ "\"" + _datFile.SHA256Count + "\"{0}"
+ "\"" + _datFile.SHA384Count + "\"{0}"
diff --git a/SabreTools.Library/Reports/Textfile.cs b/SabreTools.Library/Reports/Textfile.cs
index 3992ebb4..b51cf2ee 100644
--- a/SabreTools.Library/Reports/Textfile.cs
+++ b/SabreTools.Library/Reports/Textfile.cs
@@ -56,6 +56,7 @@ namespace SabreTools.Library.Reports
Disks found: " + _datFile.DiskCount + @"
Roms with CRC: " + _datFile.CRCCount + @"
Roms with MD5: " + _datFile.MD5Count + @"
+ Roms with RIPEMD160: " + _datFile.RIPEMD160Count + @"
Roms with SHA-1: " + _datFile.SHA1Count + @"
Roms with SHA-256: " + _datFile.SHA256Count + @"
Roms with SHA-384: " + _datFile.SHA384Count + @"
diff --git a/SabreTools.Library/SabreTools.Library.csproj b/SabreTools.Library/SabreTools.Library.csproj
index c4a9f734..03371c77 100644
--- a/SabreTools.Library/SabreTools.Library.csproj
+++ b/SabreTools.Library/SabreTools.Library.csproj
@@ -6,6 +6,10 @@
Debug;Release;Mono
AnyCPU;x64
+
+
+ NET_FRAMEWORK
+
DEBUG;TRACE;MONO
diff --git a/SabreTools.Library/Tools/Hasher.cs b/SabreTools.Library/Tools/Hasher.cs
new file mode 100644
index 00000000..9b307792
--- /dev/null
+++ b/SabreTools.Library/Tools/Hasher.cs
@@ -0,0 +1,132 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+using SabreTools.Library.Data;
+
+namespace SabreTools.Library.Tools
+{
+ public class Hasher
+ {
+ public Hash HashType { get; private set; }
+ private IDisposable _hasher;
+
+ public Hasher(Hash hashType)
+ {
+ this.HashType = hashType;
+ GetHasher();
+ }
+
+ ///
+ /// Generate the correct hashing class based on the hash type
+ ///
+ private void GetHasher()
+ {
+ switch (HashType)
+ {
+ case Hash.CRC:
+ _hasher = new OptimizedCRC();
+ break;
+
+ case Hash.MD5:
+ _hasher = MD5.Create();
+ break;
+
+#if NET_FRAMEWORK
+ case Hash.RIPEMD160:
+ _hasher = RIPEMD160.Create();
+ break;
+#endif
+
+ case Hash.SHA1:
+ _hasher = SHA1.Create();
+ break;
+
+ case Hash.SHA256:
+ _hasher = SHA256.Create();
+ break;
+
+ case Hash.SHA384:
+ _hasher = SHA384.Create();
+ break;
+
+ case Hash.SHA512:
+ _hasher = SHA512.Create();
+ break;
+ }
+ }
+
+ public void Dispose()
+ {
+ _hasher.Dispose();
+ }
+
+ public async Task Process(byte[] buffer, int size)
+ {
+ switch (HashType)
+ {
+ case Hash.CRC:
+ await Task.Run(() => (_hasher as OptimizedCRC).Update(buffer, 0, size));
+ break;
+
+ case Hash.MD5:
+#if NET_FRAMEWORK
+ case Hash.RIPEMD160:
+#endif
+ case Hash.RIPEMD160:
+ case Hash.SHA1:
+ case Hash.SHA256:
+ case Hash.SHA384:
+ case Hash.SHA512:
+ await Task.Run(() => (_hasher as HashAlgorithm).TransformBlock(buffer, 0, size, null, 0));
+ break;
+ }
+ }
+
+ public async Task Finalize()
+ {
+ byte[] emptyBuffer = new byte[0];
+ switch (HashType)
+ {
+ case Hash.CRC:
+ await Task.Run(() => (_hasher as OptimizedCRC).Update(emptyBuffer, 0, 0));
+ break;
+
+ case Hash.MD5:
+#if NET_FRAMEWORK
+ case Hash.RIPEMD160:
+#endif
+ case Hash.SHA1:
+ case Hash.SHA256:
+ case Hash.SHA384:
+ case Hash.SHA512:
+ await Task.Run(() => (_hasher as HashAlgorithm).TransformFinalBlock(emptyBuffer, 0, 0));
+ break;
+ }
+ }
+
+ public byte[] GetHash()
+ {
+ switch (HashType)
+ {
+ case Hash.CRC:
+ return BitConverter.GetBytes((_hasher as OptimizedCRC).Value).Reverse().ToArray();
+
+ case Hash.MD5:
+#if NET_FRAMEWORK
+ case Hash.RIPEMD160:
+#endif
+ case Hash.SHA1:
+ case Hash.SHA256:
+ case Hash.SHA384:
+ case Hash.SHA512:
+ return (_hasher as HashAlgorithm).Hash;
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/SabreTools.Library/Tools/Utilities.cs b/SabreTools.Library/Tools/Utilities.cs
index f13cae89..f8c364c6 100644
--- a/SabreTools.Library/Tools/Utilities.cs
+++ b/SabreTools.Library/Tools/Utilities.cs
@@ -6,6 +6,7 @@ using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
+using System.Threading.Tasks;
using System.Xml;
using System.Xml.Schema;
@@ -15,6 +16,7 @@ using SabreTools.Library.DatItems;
using SabreTools.Library.FileTypes;
using SabreTools.Library.Reports;
using SabreTools.Library.Skippers;
+using Compress.ThreadReaders;
#if MONO
using System.IO;
@@ -638,6 +640,8 @@ namespace SabreTools.Library.Tools
return new OpenMSX(baseDat);
case DatFormat.RedumpMD5:
return new Hashfile(baseDat, Hash.MD5);
+ case DatFormat.RedumpRIPEMD160:
+ return new Hashfile(baseDat, Hash.RIPEMD160);
case DatFormat.RedumpSFV:
return new Hashfile(baseDat, Hash.CRC);
case DatFormat.RedumpSHA1:
@@ -759,6 +763,8 @@ namespace SabreTools.Library.Tools
case "rc":
case "romcenter":
return DatFormat.RomCenter;
+ case "ripemd160":
+ return DatFormat.RedumpRIPEMD160;
case "sd":
case "sabredat":
return DatFormat.SabreDat;
@@ -857,6 +863,8 @@ namespace SabreTools.Library.Tools
return Field.RebuildTo;
case "region":
return Field.Region;
+ case "ripemd160":
+ return Field.RIPEMD160;
case "romof":
return Field.RomOf;
case "runnable":
@@ -1242,6 +1250,8 @@ namespace SabreTools.Library.Tools
return DatFormat.CSV;
case "md5":
return DatFormat.RedumpMD5;
+ case "ripemd160":
+ return DatFormat.RedumpRIPEMD160;
case "sfv":
return DatFormat.RedumpSFV;
case "sha1":
@@ -1366,13 +1376,11 @@ namespace SabreTools.Library.Tools
///
///