-
-
Save ChuckSavage/dc079e21563ba1402cf6c907d81ac1ca to your computer and use it in GitHub Desktop.
// Includes a mini-program for checking and fixing files that have no extension | |
// Only checks for the most common types | |
// If you create a better version, please upload it here. | |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
namespace AppendJPG | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
foreach (string file in Directory.EnumerateFiles(Environment.CurrentDirectory)) | |
{ | |
//var x = Path.GetExtension(file); | |
if (Path.GetExtension(file).Length == 0) | |
{ | |
//var n = Path.GetFileNameWithoutExtension(file); | |
IsImageExtension.ImageType type; | |
if (file.IsImage(out type)) | |
{ | |
var ext = type.ToString().ToLower(); | |
//Console.WriteLine(ext); | |
File.Move(file, file + "." + ext); | |
} | |
//var t = type; | |
} | |
} | |
} | |
} | |
public static class IsImageExtension | |
{ | |
static List<string> jpg; | |
static List<string> bmp; | |
static List<string> gif; | |
static List<string> png; | |
public enum ImageType | |
{ | |
JPG, | |
BMP, | |
GIF, | |
PNG, | |
NONE | |
} | |
const string JPG = "FF"; | |
const string BMP = "42"; | |
const string GIF = "47"; | |
const string PNG = "89"; | |
static IsImageExtension() | |
{ | |
jpg = new List<string> { "FF", "D8" }; | |
bmp = new List<string> { "42", "4D" }; | |
gif = new List<string> { "47", "49", "46" }; | |
png = new List<string> { "89", "50", "4E", "47", "0D", "0A", "1A", "0A" }; | |
} | |
public static bool IsImage(this string file, out ImageType type) | |
{ | |
type = ImageType.NONE; | |
if (string.IsNullOrWhiteSpace(file)) return false; | |
if (!File.Exists(file)) return false; | |
using (var stream = File.OpenRead(file)) | |
return stream.IsImage(out type); | |
} | |
public static bool IsImage(this Stream stream, out ImageType type) | |
{ | |
type = ImageType.NONE; | |
stream.Seek(0, SeekOrigin.Begin); | |
string bit = stream.ReadByte().ToString("X2"); | |
switch (bit) | |
{ | |
case JPG: | |
if (stream.IsImage(jpg)) | |
{ | |
type = ImageType.JPG; | |
return true; | |
} | |
break; | |
case BMP: | |
if (stream.IsImage(bmp)) | |
{ | |
type = ImageType.BMP; | |
return true; | |
} | |
break; | |
case GIF: | |
if (stream.IsImage(gif)) | |
{ | |
type = ImageType.GIF; | |
return true; | |
} | |
break; | |
case PNG: | |
if (stream.IsImage(png)) | |
{ | |
type = ImageType.PNG; | |
return true; | |
} | |
break; | |
default: | |
break; | |
} | |
return false; | |
} | |
public static bool IsImage(this Stream stream, List<string> comparer) | |
{ | |
stream.Seek(0, SeekOrigin.Begin); | |
foreach (string c in comparer) | |
{ | |
string bit = stream.ReadByte().ToString("X2"); | |
if (0 != string.Compare(bit, c)) | |
return false; | |
} | |
return true; | |
} | |
} | |
} |
@Freshmintyy they are wildly available on the Internet. One is on Wikipedia: https://en.m.wikipedia.org/wiki/List_of_file_signatures
Other one: https://www.garykessler.net/library/file_sigs.html
Search for Magic Numbers, File Headers etc. there are also nugets for .NET that have these lists and functions to check. Be aware that there are thousands and thousands file types, checking them all without any index would be very slow and resource hungry. Therefore either use indexes, divide for parallel processing etc. or, in cases such as this, just pick couple of signatures you really need and check only against them.
Hi @EvilVir
We have a small error here.
When the appropriate code is found in the header, it is necessary to return the stream to the beginning before the return statement.
if (slice.SequenceEqual(check.Value))
{
data.Seek(0, SeekOrigin.Begin);
return check.Key;
}
This is the perfect solution for anyone looking to verify that a file is of a certain file type. @EvilVir do you have a link to find the byte arrays for other file types?