85 lines
3.0 KiB
C#
85 lines
3.0 KiB
C#
namespace Explorer.Domain;
|
|
|
|
/// <summary>Light magic-byte hints for files with no useful extension category.</summary>
|
|
public static class FileSignatureClassifier
|
|
{
|
|
public static FileClassification? TryClassify(ReadOnlySpan<byte> header)
|
|
{
|
|
if (header.Length < 4)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
if (header[0] == 0xFF && header[1] == 0xD8 && header[2] == 0xFF)
|
|
{
|
|
return new FileClassification(FileCategory.Photos, "JPEG signature.");
|
|
}
|
|
|
|
if (header.Length >= 8
|
|
&& header[0] == 0x89 && header[1] == 0x50 && header[2] == 0x4E && header[3] == 0x47)
|
|
{
|
|
return new FileClassification(FileCategory.Photos, "PNG signature.");
|
|
}
|
|
|
|
if (header[0] == 0x47 && header[1] == 0x49 && header[2] == 0x46 && header[3] == 0x38)
|
|
{
|
|
return new FileClassification(FileCategory.Photos, "GIF signature.");
|
|
}
|
|
|
|
if (header[0] == 0x25 && header[1] == 0x50 && header[2] == 0x44 && header[3] == 0x46)
|
|
{
|
|
return new FileClassification(FileCategory.Documents, "PDF signature.");
|
|
}
|
|
|
|
if (header[0] == 0x50 && header[1] == 0x4B && (header[2] == 0x03 || header[2] == 0x05 || header[2] == 0x07))
|
|
{
|
|
return new FileClassification(FileCategory.Archive, "ZIP-family signature.");
|
|
}
|
|
|
|
if (header.Length >= 12
|
|
&& header[0] == 0x52 && header[1] == 0x49 && header[2] == 0x46 && header[3] == 0x46)
|
|
{
|
|
var form = System.Text.Encoding.ASCII.GetString(header.Slice(8, 4));
|
|
if (form is "WAVE" or "AVI ")
|
|
{
|
|
return new FileClassification(
|
|
form == "WAVE" ? FileCategory.Audio : FileCategory.Video,
|
|
"RIFF " + form.Trim() + " signature.");
|
|
}
|
|
}
|
|
|
|
if (header.Length >= 12
|
|
&& header[4] == 0x66 && header[5] == 0x74 && header[6] == 0x79 && header[7] == 0x70)
|
|
{
|
|
return new FileClassification(FileCategory.Video, "ISO BMFF (ftyp) signature.");
|
|
}
|
|
|
|
if (header[0] == 0x49 && header[1] == 0x44 && header[2] == 0x33)
|
|
{
|
|
return new FileClassification(FileCategory.Audio, "ID3 signature.");
|
|
}
|
|
|
|
if (header[0] == 0x7F && header[1] == 0x45 && header[2] == 0x4C && header[3] == 0x46)
|
|
{
|
|
return new FileClassification(FileCategory.Installer, "ELF binary signature.");
|
|
}
|
|
|
|
if (header[0] == 0x4D && header[1] == 0x5A)
|
|
{
|
|
return new FileClassification(FileCategory.Installer, "PE/MZ signature.");
|
|
}
|
|
|
|
if (header[0] == 0x37 && header[1] == 0x7A && header[2] == 0xBC && header[3] == 0xAF)
|
|
{
|
|
return new FileClassification(FileCategory.Archive, "7z signature.");
|
|
}
|
|
|
|
if (header[0] == 0x52 && header[1] == 0x61 && header[2] == 0x72 && header[3] == 0x21)
|
|
{
|
|
return new FileClassification(FileCategory.Archive, "RAR signature.");
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|