mirror of
https://github.com/SabreTools/SabreTools.Serialization.git
synced 2026-04-05 22:01:33 +00:00
564 lines
20 KiB
C#
564 lines
20 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using SabreTools.Data.Models.Hashfile;
|
|
using SabreTools.Hashing;
|
|
|
|
#pragma warning disable CA1822 // Mark members as static
|
|
namespace SabreTools.Serialization.Readers
|
|
{
|
|
public class Hashfile : BaseBinaryReader<Data.Models.Hashfile.Hashfile>
|
|
{
|
|
#region IByteReader
|
|
|
|
/// <inheritdoc/>
|
|
public override Data.Models.Hashfile.Hashfile? Deserialize(byte[]? data, int offset)
|
|
=> Deserialize(data, offset, HashType.CRC32);
|
|
|
|
/// <inheritdoc cref="Deserialize(byte[], int)"/>
|
|
public Data.Models.Hashfile.Hashfile? Deserialize(byte[]? data, int offset, HashType hash)
|
|
{
|
|
// If the data is invalid
|
|
if (data is null || data.Length == 0)
|
|
return null;
|
|
|
|
// If the offset is out of bounds
|
|
if (offset < 0 || offset >= data.Length)
|
|
return null;
|
|
|
|
// Create a memory stream and parse that
|
|
var dataStream = new MemoryStream(data, offset, data.Length - offset);
|
|
return Deserialize(dataStream, hash);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IFileReader
|
|
|
|
/// <inheritdoc/>
|
|
public override Data.Models.Hashfile.Hashfile? Deserialize(string? path)
|
|
=> Deserialize(path, HashType.CRC32);
|
|
|
|
/// <inheritdoc cref="Deserialize(string?)"/>
|
|
public Data.Models.Hashfile.Hashfile? Deserialize(string? path, HashType hash)
|
|
{
|
|
try
|
|
{
|
|
// If we don't have a file
|
|
if (string.IsNullOrEmpty(path) || !File.Exists(path))
|
|
return default;
|
|
|
|
// Open the file for deserialization
|
|
using var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
|
return Deserialize(stream, hash);
|
|
}
|
|
catch
|
|
{
|
|
// TODO: Handle logging the exception
|
|
return default;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IStreamReader
|
|
|
|
public override Data.Models.Hashfile.Hashfile? Deserialize(Stream? data)
|
|
=> Deserialize(data, HashType.CRC32);
|
|
|
|
/// <inheritdoc cref="Deserialize(Stream)"/>
|
|
public Data.Models.Hashfile.Hashfile? Deserialize(Stream? data, HashType hash)
|
|
{
|
|
if (hash == HashType.CRC32)
|
|
return DeserializeSFV(data);
|
|
else if (hash == HashType.MD2)
|
|
return DeserializeMD2(data);
|
|
else if (hash == HashType.MD4)
|
|
return DeserializeMD4(data);
|
|
else if (hash == HashType.MD5)
|
|
return DeserializeMD5(data);
|
|
else if (hash == HashType.RIPEMD128)
|
|
return DeserializeRIPEMD128(data);
|
|
else if (hash == HashType.RIPEMD160)
|
|
return DeserializeRIPEMD160(data);
|
|
else if (hash == HashType.SHA1)
|
|
return DeserializeSHA1(data);
|
|
else if (hash == HashType.SHA256)
|
|
return DeserializeSHA256(data);
|
|
else if (hash == HashType.SHA384)
|
|
return DeserializeSHA384(data);
|
|
else if (hash == HashType.SHA512)
|
|
return DeserializeSHA512(data);
|
|
else if (hash == HashType.SpamSum)
|
|
return DeserializeSpamSum(data);
|
|
else
|
|
return null;
|
|
}
|
|
|
|
/// <inheritdoc cref="Deserialize(Stream)"/>
|
|
public Data.Models.Hashfile.Hashfile? DeserializeSFV(Stream? data)
|
|
{
|
|
// If the data is invalid
|
|
if (data is null || !data.CanRead)
|
|
return null;
|
|
|
|
try
|
|
{
|
|
// Setup the reader and output
|
|
var reader = new StreamReader(data);
|
|
var sfvList = new List<SFV>();
|
|
|
|
// Loop through the rows and parse out values
|
|
while (!reader.EndOfStream)
|
|
{
|
|
// Read and split the line
|
|
string? line = reader.ReadLine();
|
|
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
|
if (lineParts is null || lineParts.Length < 2)
|
|
continue;
|
|
|
|
var sfv = new SFV
|
|
{
|
|
File = string.Join(" ", lineParts, 0, lineParts.Length - 1),
|
|
#if NETCOREAPP || NETSTANDARD2_1_OR_GREATER
|
|
Hash = lineParts[^1],
|
|
#else
|
|
Hash = lineParts[lineParts.Length - 1],
|
|
#endif
|
|
};
|
|
sfvList.Add(sfv);
|
|
}
|
|
|
|
// Assign the hashes to the hashfile and return
|
|
if (sfvList.Count > 0)
|
|
return new Data.Models.Hashfile.Hashfile { SFV = [.. sfvList] };
|
|
|
|
return null;
|
|
}
|
|
catch
|
|
{
|
|
// Ignore the actual error
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc cref="Deserialize(Stream)"/>
|
|
public Data.Models.Hashfile.Hashfile? DeserializeMD2(Stream? data)
|
|
{
|
|
// If the data is invalid
|
|
if (data is null || !data.CanRead)
|
|
return null;
|
|
|
|
try
|
|
{
|
|
// Setup the reader and output
|
|
var reader = new StreamReader(data);
|
|
var md2List = new List<MD2>();
|
|
|
|
// Loop through the rows and parse out values
|
|
while (!reader.EndOfStream)
|
|
{
|
|
// Read and split the line
|
|
string? line = reader.ReadLine();
|
|
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
|
if (lineParts is null || lineParts.Length < 2)
|
|
continue;
|
|
|
|
// Parse the line into a hash
|
|
var md2 = new MD2
|
|
{
|
|
Hash = lineParts[0],
|
|
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
|
|
};
|
|
md2List.Add(md2);
|
|
}
|
|
|
|
// Assign the hashes to the hashfile and return
|
|
if (md2List.Count > 0)
|
|
return new Data.Models.Hashfile.Hashfile { MD2 = [.. md2List] };
|
|
|
|
return null;
|
|
}
|
|
catch
|
|
{
|
|
// Ignore the actual error
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc cref="Deserialize(Stream)"/>
|
|
public Data.Models.Hashfile.Hashfile? DeserializeMD4(Stream? data)
|
|
{
|
|
// If the data is invalid
|
|
if (data is null || !data.CanRead)
|
|
return null;
|
|
|
|
try
|
|
{
|
|
// Setup the reader and output
|
|
var reader = new StreamReader(data);
|
|
var md4List = new List<MD4>();
|
|
|
|
// Loop through the rows and parse out values
|
|
while (!reader.EndOfStream)
|
|
{
|
|
// Read and split the line
|
|
string? line = reader.ReadLine();
|
|
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
|
if (lineParts is null || lineParts.Length < 2)
|
|
continue;
|
|
|
|
// Parse the line into a hash
|
|
var md4 = new MD4
|
|
{
|
|
Hash = lineParts[0],
|
|
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
|
|
};
|
|
md4List.Add(md4);
|
|
}
|
|
|
|
// Assign the hashes to the hashfile and return
|
|
if (md4List.Count > 0)
|
|
return new Data.Models.Hashfile.Hashfile { MD4 = [.. md4List] };
|
|
|
|
return null;
|
|
}
|
|
catch
|
|
{
|
|
// Ignore the actual error
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc cref="Deserialize(Stream)"/>
|
|
public Data.Models.Hashfile.Hashfile? DeserializeMD5(Stream? data)
|
|
{
|
|
// If the data is invalid
|
|
if (data is null || !data.CanRead)
|
|
return null;
|
|
|
|
// Setup the reader and output
|
|
var reader = new StreamReader(data);
|
|
var md5List = new List<MD5>();
|
|
|
|
// Loop through the rows and parse out values
|
|
while (!reader.EndOfStream)
|
|
{
|
|
// Read and split the line
|
|
string? line = reader.ReadLine();
|
|
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
|
if (lineParts is null || lineParts.Length < 2)
|
|
continue;
|
|
|
|
// Parse the line into a hash
|
|
var md5 = new MD5
|
|
{
|
|
Hash = lineParts[0],
|
|
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
|
|
};
|
|
md5List.Add(md5);
|
|
}
|
|
|
|
// Assign the hashes to the hashfile and return
|
|
if (md5List.Count > 0)
|
|
return new Data.Models.Hashfile.Hashfile { MD5 = [.. md5List] };
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <inheritdoc cref="Deserialize(Stream)"/>
|
|
public Data.Models.Hashfile.Hashfile? DeserializeRIPEMD128(Stream? data)
|
|
{
|
|
// If the data is invalid
|
|
if (data is null || !data.CanRead)
|
|
return null;
|
|
|
|
// Setup the reader and output
|
|
var reader = new StreamReader(data);
|
|
var ripemd128List = new List<RIPEMD128>();
|
|
|
|
// Loop through the rows and parse out values
|
|
while (!reader.EndOfStream)
|
|
{
|
|
// Read and split the line
|
|
string? line = reader.ReadLine();
|
|
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
|
if (lineParts is null || lineParts.Length < 2)
|
|
continue;
|
|
|
|
// Parse the line into a hash
|
|
var ripemd128 = new RIPEMD128
|
|
{
|
|
Hash = lineParts[0],
|
|
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
|
|
};
|
|
ripemd128List.Add(ripemd128);
|
|
}
|
|
|
|
// Assign the hashes to the hashfile and return
|
|
if (ripemd128List.Count > 0)
|
|
return new Data.Models.Hashfile.Hashfile { RIPEMD128 = [.. ripemd128List] };
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <inheritdoc cref="Deserialize(Stream)"/>
|
|
public Data.Models.Hashfile.Hashfile? DeserializeRIPEMD160(Stream? data)
|
|
{
|
|
// If the data is invalid
|
|
if (data is null || !data.CanRead)
|
|
return null;
|
|
|
|
// Setup the reader and output
|
|
var reader = new StreamReader(data);
|
|
var ripemd160List = new List<RIPEMD160>();
|
|
|
|
// Loop through the rows and parse out values
|
|
while (!reader.EndOfStream)
|
|
{
|
|
// Read and split the line
|
|
string? line = reader.ReadLine();
|
|
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
|
if (lineParts is null || lineParts.Length < 2)
|
|
continue;
|
|
|
|
// Parse the line into a hash
|
|
var ripemd160 = new RIPEMD160
|
|
{
|
|
Hash = lineParts[0],
|
|
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
|
|
};
|
|
ripemd160List.Add(ripemd160);
|
|
}
|
|
|
|
// Assign the hashes to the hashfile and return
|
|
if (ripemd160List.Count > 0)
|
|
return new Data.Models.Hashfile.Hashfile { RIPEMD160 = [.. ripemd160List] };
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <inheritdoc cref="Deserialize(Stream)"/>
|
|
public Data.Models.Hashfile.Hashfile? DeserializeSHA1(Stream? data)
|
|
{
|
|
// If the data is invalid
|
|
if (data is null || !data.CanRead)
|
|
return null;
|
|
|
|
try
|
|
{
|
|
// Setup the reader and output
|
|
var reader = new StreamReader(data);
|
|
var sha1List = new List<SHA1>();
|
|
|
|
// Loop through the rows and parse out values
|
|
while (!reader.EndOfStream)
|
|
{
|
|
// Read and split the line
|
|
string? line = reader.ReadLine();
|
|
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
|
if (lineParts is null || lineParts.Length < 2)
|
|
continue;
|
|
|
|
// Parse the line into a hash
|
|
var sha1 = new SHA1
|
|
{
|
|
Hash = lineParts[0],
|
|
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
|
|
};
|
|
sha1List.Add(sha1);
|
|
}
|
|
|
|
// Assign the hashes to the hashfile and return
|
|
if (sha1List.Count > 0)
|
|
return new Data.Models.Hashfile.Hashfile { SHA1 = [.. sha1List] };
|
|
|
|
return null;
|
|
}
|
|
catch
|
|
{
|
|
// Ignore the actual error
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc cref="Deserialize(Stream)"/>
|
|
public Data.Models.Hashfile.Hashfile? DeserializeSHA256(Stream? data)
|
|
{
|
|
// If the data is invalid
|
|
if (data is null || !data.CanRead)
|
|
return null;
|
|
|
|
try
|
|
{
|
|
// Setup the reader and output
|
|
var reader = new StreamReader(data);
|
|
var sha256List = new List<SHA256>();
|
|
|
|
// Loop through the rows and parse out values
|
|
while (!reader.EndOfStream)
|
|
{
|
|
// Read and split the line
|
|
string? line = reader.ReadLine();
|
|
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
|
if (lineParts is null || lineParts.Length < 2)
|
|
continue;
|
|
|
|
// Parse the line into a hash
|
|
var sha256 = new SHA256
|
|
{
|
|
Hash = lineParts[0],
|
|
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
|
|
};
|
|
sha256List.Add(sha256);
|
|
}
|
|
|
|
// Assign the hashes to the hashfile and return
|
|
if (sha256List.Count > 0)
|
|
return new Data.Models.Hashfile.Hashfile { SHA256 = [.. sha256List] };
|
|
|
|
return null;
|
|
}
|
|
catch
|
|
{
|
|
// Ignore the actual error
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc cref="Deserialize(Stream)"/>
|
|
public Data.Models.Hashfile.Hashfile? DeserializeSHA384(Stream? data)
|
|
{
|
|
// If the data is invalid
|
|
if (data is null || !data.CanRead)
|
|
return null;
|
|
|
|
try
|
|
{
|
|
// Setup the reader and output
|
|
var reader = new StreamReader(data);
|
|
var sha384List = new List<SHA384>();
|
|
|
|
// Loop through the rows and parse out values
|
|
while (!reader.EndOfStream)
|
|
{
|
|
// Read and split the line
|
|
string? line = reader.ReadLine();
|
|
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
|
if (lineParts is null || lineParts.Length < 2)
|
|
continue;
|
|
|
|
// Parse the line into a hash
|
|
var sha384 = new SHA384
|
|
{
|
|
Hash = lineParts[0],
|
|
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
|
|
};
|
|
sha384List.Add(sha384);
|
|
}
|
|
|
|
// Assign the hashes to the hashfile and return
|
|
if (sha384List.Count > 0)
|
|
return new Data.Models.Hashfile.Hashfile { SHA384 = [.. sha384List] };
|
|
|
|
return null;
|
|
}
|
|
catch
|
|
{
|
|
// Ignore the actual error
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc cref="Deserialize(Stream)"/>
|
|
public Data.Models.Hashfile.Hashfile? DeserializeSHA512(Stream? data)
|
|
{
|
|
// If the data is invalid
|
|
if (data is null || !data.CanRead)
|
|
return null;
|
|
|
|
try
|
|
{
|
|
// Setup the reader and output
|
|
var reader = new StreamReader(data);
|
|
var sha512List = new List<SHA512>();
|
|
|
|
// Loop through the rows and parse out values
|
|
while (!reader.EndOfStream)
|
|
{
|
|
// Read and split the line
|
|
string? line = reader.ReadLine();
|
|
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
|
if (lineParts is null || lineParts.Length < 2)
|
|
continue;
|
|
|
|
// Parse the line into a hash
|
|
var sha512 = new SHA512
|
|
{
|
|
Hash = lineParts[0],
|
|
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
|
|
};
|
|
sha512List.Add(sha512);
|
|
}
|
|
|
|
// Assign the hashes to the hashfile and return
|
|
if (sha512List.Count > 0)
|
|
return new Data.Models.Hashfile.Hashfile { SHA512 = [.. sha512List] };
|
|
|
|
return null;
|
|
}
|
|
catch
|
|
{
|
|
// Ignore the actual error
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc cref="Deserialize(Stream)"/>
|
|
public Data.Models.Hashfile.Hashfile? DeserializeSpamSum(Stream? data)
|
|
{
|
|
// If the data is invalid
|
|
if (data is null || !data.CanRead)
|
|
return default;
|
|
|
|
try
|
|
{
|
|
// Setup the reader and output
|
|
var reader = new StreamReader(data);
|
|
var spamsumList = new List<SpamSum>();
|
|
|
|
// Loop through the rows and parse out values
|
|
while (!reader.EndOfStream)
|
|
{
|
|
// Read and split the line
|
|
string? line = reader.ReadLine();
|
|
string[]? lineParts = line?.Split([' '], StringSplitOptions.RemoveEmptyEntries);
|
|
if (lineParts is null || lineParts.Length < 2)
|
|
continue;
|
|
|
|
// Parse the line into a hash
|
|
var spamSum = new SpamSum
|
|
{
|
|
Hash = lineParts[0],
|
|
File = string.Join(" ", lineParts, 1, lineParts.Length - 1),
|
|
};
|
|
spamsumList.Add(spamSum);
|
|
}
|
|
|
|
// Assign the hashes to the hashfile and return
|
|
if (spamsumList.Count > 0)
|
|
return new Data.Models.Hashfile.Hashfile { SpamSum = [.. spamsumList] };
|
|
|
|
return null;
|
|
}
|
|
catch
|
|
{
|
|
// Ignore the actual error
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|