txt文本的魔数到底是多少
做附件上传,需要校验文件的真实格式,现场反应txt文本无法上传。测试验证:
public static final Map<String, String> TYPES = new HashMap<String, String>();
static {
// 图片,此处只提取前六位作为魔数
TYPES.put("706163", "txt");
TYPES.put("5B0A20", "txt");// 20191202 找了txt验证是这个数值
TYPES.put("C4DCD4", "txt");// 20191203 后来又找了txt验证是这个数值
TYPES.put("E69D80", "txt");// 20191203 再建了txt验证是这个数值
TYPES.put("E5958A", "txt");// 20191203 再建了txt验证是这个数值
}
/**
* 上传文件类型判断,是否符合要求的格式
* @param uploadFile
* @param needType
* @return
*/
public static boolean checkFileType(MultipartFile uploadFile,String needType)throws IOException {
try {
byte[] imgBytes = uploadFile.getBytes();
String realType=null;
//现在定义的魔数位数 最短是4位 最长是到了28位 应该每个都判断一次
for(int i=4;i<30;i++){
//提取前六位作为魔数 这个不准
String magicNumberHex = getHex(imgBytes, i);
String realTypeTemp=TYPES.get(magicNumberHex);
if(realTypeTemp!=null){
realType=realTypeTemp;
break;
}
}
if(realType!=null){//没有定义的文件类型就
//禁止上传php,php3,php5,phtml,asp,aspx,ascx,jsp,cfm,cfc,pl,bat,exe,dll,reg,cgi
String ban=",php,php3,php5,phtml,asp,aspx,ascx,jsp,cfm,cfc,pl,bat,exe,dll,reg,cgi,";
if(ban.indexOf(","+realType+",")>-1){//先校验 不能上传的文件类型
return false;
}
if(StringUtils.isNullOrEmpty(needType)){//上传的文件要求类型为空的时候 就直接返回
return true;
}
String arr[]=needType.split(",");
for(int i=0;i<arr.length;i++){
if(realType.equals(arr[i])){//只要有一个满足就是符合条件的文件格式
return true;
}
}
return false;
}else{
return false;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
/**
* 获取16进制表示的魔数
*
* @param data 字节数组形式的文件数据
* @param magicNumberLength 魔数长度
* @return
*/
public static String getHex(byte[] data, int magicNumberLength) {
//提取文件的魔数
StringBuilder magicNumber = new StringBuilder();
//一个字节对应魔数的两位
int magicNumberByteLength = magicNumberLength / 2;
for (int i = 0; i < magicNumberByteLength; i++) {
magicNumber.append(Integer.toHexString(data[i] >> 4 & 0xF));
magicNumber.append(Integer.toHexString(data[i] & 0xF));
}
return magicNumber.toString().toUpperCase();
}
这是什么情况?每建一个txt是一个新的魔数 这没法玩了。。。
想了想,我建的测试txt文本 都建完随便输了点内容,不会和我输入的内容有关吧?把几个测试的txt文本内容改成一样的,重新上传验证,果然如此!! 所以我认为txt没法校验魔数,虽然我没啥理论来证实这点,纯粹验证经验推论的。so,如果是txt后缀的就不校验魔数了。
-------------------------------------------------------------------------------------------------------------------------------------------
后来 发现 pptx和 vsdx的 魔数是 一样的
对比了的长度 都一样
magicNumberHex=504B
magicNumberHex=504B03
magicNumberHex=504B0304
magicNumberHex=504B030414
magicNumberHex=504B03041400
magicNumberHex=504B0304140006
magicNumberHex=504B030414000600
magicNumberHex=504B03041400060008
magicNumberHex=504B0304140006000800
magicNumberHex=504B030414000600080000
magicNumberHex=504B03041400060008000000
magicNumberHex=504B0304140006000800000021
magicNumberHex=504B030414000600080000002100
推荐阅读