diff --git a/InfoPrint/InfoPrint.csproj b/InfoPrint/InfoPrint.csproj
index a93a591a..0b8f8cb1 100644
--- a/InfoPrint/InfoPrint.csproj
+++ b/InfoPrint/InfoPrint.csproj
@@ -32,6 +32,7 @@
+
\ No newline at end of file
diff --git a/InfoPrint/Options.cs b/InfoPrint/Options.cs
index b0ffe96e..a83e3d84 100644
--- a/InfoPrint/Options.cs
+++ b/InfoPrint/Options.cs
@@ -15,6 +15,11 @@ namespace InfoPrint
///
public bool Debug { get; private set; } = false;
+ ///
+ /// Print external file hashes
+ ///
+ public bool Hash { get; private set; } = false;
+
///
/// Set of input paths to use for operations
///
@@ -74,6 +79,11 @@ namespace InfoPrint
options.Debug = true;
break;
+ case "-c":
+ case "--hash":
+ options.Hash = true;
+ break;
+
case "-j":
case "--json":
#if NETCOREAPP
@@ -111,6 +121,7 @@ namespace InfoPrint
Console.WriteLine("Options:");
Console.WriteLine("-?, -h, --help Display this help text and quit");
Console.WriteLine("-d, --debug Enable debug mode");
+ Console.WriteLine("-c, --hash Output file hashes");
#if NETCOREAPP
Console.WriteLine("-j, --json Print info as JSON");
#endif
diff --git a/InfoPrint/Program.cs b/InfoPrint/Program.cs
index 1459be9a..ac21a934 100644
--- a/InfoPrint/Program.cs
+++ b/InfoPrint/Program.cs
@@ -1,5 +1,7 @@
using System;
using System.IO;
+using System.Text;
+using SabreTools.Hashing;
using SabreTools.IO.Extensions;
using SabreTools.Serialization;
using SabreTools.Serialization.Wrappers;
@@ -24,9 +26,9 @@ namespace InfoPrint
foreach (string inputPath in options.InputPaths)
{
#if NETFRAMEWORK || NETSTANDARD2_0_OR_GREATER
- PrintPathInfo(inputPath, false, options.Debug);
+ PrintPathInfo(inputPath, false, options.Debug, options.Hash);
#else
- PrintPathInfo(inputPath, options.Json, options.Debug);
+ PrintPathInfo(inputPath, options.Json, options.Debug, options.Hash);
#endif
}
}
@@ -37,20 +39,21 @@ namespace InfoPrint
/// File or directory path
/// Enable JSON output, if supported
/// Enable debug output
- private static void PrintPathInfo(string path, bool json, bool debug)
+ /// Enable hash output
+ private static void PrintPathInfo(string path, bool json, bool debug, bool hash)
{
Console.WriteLine($"Checking possible path: {path}");
// Check if the file or directory exists
if (File.Exists(path))
{
- PrintFileInfo(path, json, debug);
+ PrintFileInfo(path, json, debug, hash);
}
else if (Directory.Exists(path))
{
foreach (string file in IOExtensions.SafeEnumerateFiles(path, "*", SearchOption.AllDirectories))
{
- PrintFileInfo(file, json, debug);
+ PrintFileInfo(file, json, debug, hash);
}
}
else
@@ -62,10 +65,19 @@ namespace InfoPrint
///
/// Print information for a single file, if possible
///
- private static void PrintFileInfo(string file, bool json, bool debug)
+ /// File path
+ /// Enable JSON output, if supported
+ /// Enable debug output
+ /// Enable hash output
+ private static void PrintFileInfo(string file, bool json, bool debug, bool hash)
{
Console.WriteLine($"Attempting to print info for {file}");
+ // Retrieve hashes before anything else, if required
+ StringBuilder? hashBuilder = null;
+ if (hash)
+ hashBuilder = PrintHashInfo(file, debug);
+
try
{
using Stream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
@@ -101,7 +113,6 @@ namespace InfoPrint
{
// Create the output data
string serializedData = wrapper.ExportJSON();
- Console.WriteLine(serializedData);
// Write the output data
using var jsw = new StreamWriter(File.OpenWrite($"{filenameBase}.json"));
@@ -118,9 +129,19 @@ namespace InfoPrint
}
// Write the output data
+ if (hashBuilder != null)
+ {
+ Console.WriteLine(hashBuilder);
+ Console.WriteLine();
+ }
+
Console.WriteLine(builder);
using var sw = new StreamWriter(File.OpenWrite($"{filenameBase}.txt"));
+ if (hashBuilder != null)
+ sw.WriteLine(hashBuilder.ToString());
+
sw.WriteLine(builder.ToString());
+ sw.Flush();
}
catch (Exception ex)
{
@@ -128,5 +149,63 @@ namespace InfoPrint
Console.WriteLine();
}
}
+
+ ///
+ /// Print hash information for a single file, if possible
+ ///
+ /// File path
+ /// Enable debug output
+ /// StringBuilder representing the hash information, if possible
+ private static StringBuilder? PrintHashInfo(string file, bool debug)
+ {
+ // Ignore missing files
+ if (!File.Exists(file))
+ return null;
+
+ Console.WriteLine($"Attempting to hash {file}, this may take a while...");
+
+ try
+ {
+ // Get all file hashes for flexibility
+ var hashes = HashTool.GetFileHashes(file);
+ if (hashes == null)
+ {
+ if (debug) Console.WriteLine($"Hashes for {file} could not be retrieved");
+ return null;
+ }
+
+ // Output subset of available hashes
+ var builder = new StringBuilder();
+ if (hashes.TryGetValue(HashType.CRC16, out string? crc16) && crc16 != null)
+ builder.AppendLine($"CRC-16 checksum: {crc16}");
+ if (hashes.TryGetValue(HashType.CRC32, out string? crc32) && crc32 != null)
+ builder.AppendLine($"CRC-32 checksum: {crc32}");
+ if (hashes.TryGetValue(HashType.MD2, out string? md2) && md2 != null)
+ builder.AppendLine($"MD2 hash: {md2}");
+ if (hashes.TryGetValue(HashType.MD4, out string? md4) && md4 != null)
+ builder.AppendLine($"MD4 hash: {md4}");
+ if (hashes.TryGetValue(HashType.MD5, out string? md5) && md5 != null)
+ builder.AppendLine($"MD5 hash: {md5}");
+ if (hashes.TryGetValue(HashType.RIPEMD128, out string? ripemd128) && ripemd128 != null)
+ builder.AppendLine($"RIPEMD-128 hash: {ripemd128}");
+ if (hashes.TryGetValue(HashType.RIPEMD160, out string? ripemd160) && ripemd160 != null)
+ builder.AppendLine($"RIPEMD-160 hash: {ripemd160}");
+ if (hashes.TryGetValue(HashType.SHA1, out string? sha1) && sha1 != null)
+ builder.AppendLine($"SHA-1 hash: {sha1}");
+ if (hashes.TryGetValue(HashType.SHA256, out string? sha256) && sha256 != null)
+ builder.AppendLine($"SHA-256 hash: {sha256}");
+ if (hashes.TryGetValue(HashType.SHA384, out string? sha384) && sha384 != null)
+ builder.AppendLine($"SHA-384 hash: {sha384}");
+ if (hashes.TryGetValue(HashType.SHA512, out string? sha512) && sha512 != null)
+ builder.AppendLine($"SHA-512 hash: {sha512}");
+
+ return builder;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(debug ? ex : "[Exception opening file, please try again]");
+ return null;
+ }
+ }
}
}