基于文件头特征码的格式识别实践
在文件上传或处理场景中,仅靠后缀名判断文件类型往往不可靠。更稳妥的方式是读取文件开头的几个字节,对比其十六进制特征值(俗称'魔数')。
核心原理
每种文件格式都有固定的二进制头部标识。例如 JPEG 以 FF D8 FF 开头,PNG 则是 89 50 4E 47。通过读取文件前缀并转换为十六进制字符串进行比对,即可准确识别。
代码实现
public class FileTypeJudge {
public enum FileType {
JPG("FFD8FFE000104A464946"),
PNG("89504E470D0A1A0A0000"),
GIF("47494638396126026F01"),
TIF("49492A00227105008037"),
BMP16("424D228C010000000000"), // 16 色位图
BMP24("424D8240090000000000"), // 24 位位图
BMP256("424D8E1B030000000000"), // 256 色位图
DWG("41433130313500000000"),
HTML("3C21444F435459504520"),
HTM("3C21646F637479706520"),
CSS("48544D4C207B0D0A0942"),
JS("696B2E71623D696B2E71"),
RTF("7B5C727466315C616E73"),
PSD("38425053000100000000"),
EML("46726F6D3A203D3F6762"),
DOC("D0CF11E0A1B11AE10000"), // Word, Excel, Msi
VSD("D0CF11E0A1B11AE10000"),
MDB("5374616E64617264204A"),
PDF("255044462D312E350D0A"),
RMVB("2E524D46000000120001"),
FLV("464C5601050000000900"),
MP4("00000020667479706D70"),
MP3("49443303000000002176"),
MPG("000001BA210001000180"),
WMV(),
WAV(),
AVI(),
MID(),
ZIP(),
RAR(),
INI(),
JAR(),
EXE(),
JSP(),
MF(),
XML(),
SQL(),
JAVA(),
BAT(),
GZ(),
PROPERTIES(),
CLASS(),
CHM(),
MXP(),
DOCX(),
WPS(),
TORRENT(),
MOV(),
WPD(),
DBX(),
PST(),
QDF(),
PWL(),
RAM();
;
{
.value = value;
}
String {
value;
}
}
{}
String {
();
(src == || src.length <= ) {
;
}
( ; i < src.length; i++) {
src[i] & ;
Integer.toHexString(v);
(hv.length() < ) {
stringBuilder.append();
}
stringBuilder.append(hv);
}
stringBuilder.toString();
}
FileType Exception {
(path);
(file);
[] b = [];
fis.read(b, , b.length);
fis.close();
bytesToHex(b);
FileType[] fileTypes = FileType.values();
(FileType type : fileTypes) {
(fileCode.toUpperCase().startsWith(type.getValue().trim())) {
type;
}
}
;
}
Exception {
System.out.println(FileTypeJudge.getFileType());
}
}

