文件格式校验(文件二进制内容校验)
常见文件的二进制标识
- JPEG/JPG - 文件头标识 (2 bytes): ff, d8 文件结束标识 (2 bytes): ff, d9
- TGA - 未压缩的前 5 字节 00 00 02 00 00 - RLE 压缩的前 5 字节 00 00 10 00 00
- PNG - 文件头标识 (8 bytes) 89 50 4E 47 0D 0A 1A 0A
- GIF - 文件头标识 (6 bytes) 47 49 46 38 39(37) 61
- BMP - 文件头标识 (2 bytes) 42 4D B M
- PCX - 文件头标识 (1 bytes) 0A
- TIFF - 文件头标识 (2 bytes) 4D 4D 或 49 49
- ICO - 文件头标识 (8 bytes) 00 00 01 00 01 00 20 20
- CUR - 文件头标识 (8 bytes) 00 00 02 00 01 00 20 20
- IFF - 文件头标识 (4 bytes) 46 4F 52 4D
- ANI - 文件头标识 (4 bytes) 52 49 46 46
vue
<template>
<div>
<input type="file" id="inputFile" @change="handleChange" />
</div>
</template>
<script>
export default {
name: "HelloWorld",
methods: {
check(headers) {
return (buffers, options = { offset: 0 }) =>
headers.every((header, index) => header === buffers[options.offset + index]);
},
async handleChange(event) {
const file = event.target.files[0];
// 以PNG为例,只需要获取前8个字节,即可识别其类型
const buffers = await this.readBuffer(file, 0, 8);
const uint8Array = new Uint8Array(buffers);
const isPNG = this.check([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
// 上传test.png后,打印结果为true
console.log(isPNG(uint8Array))
},
readBuffer(file, start = 0, end = 2) {
// 获取文件的二进制数据,因为我们只需要校验前几个字节即可,所以并不需要获取整个文件的数据
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = reject;
reader.readAsArrayBuffer(file.slice(start, end));
});
}
}
};
</script>