【图片服务】校验上传图片真实格式、伪后缀校验、文件魔术校验

编程入门 行业动态 更新时间:2024-10-09 22:16:14

【图片服务】校验上传图片真实格式、伪<a href=https://www.elefans.com/category/jswz/34/1765788.html style=后缀校验、文件魔术校验"/>

【图片服务】校验上传图片真实格式、伪后缀校验、文件魔术校验

工具类

import com.googlemon.collect.Lists;import java.io.*;
import java.util.Arrays;
import java.util.List;public class FileUtil {/*** 删除** @param dir*/public static void deleteAll(File dir) {if (dir.isFile()) {ApiLogger.info(String.format("delete file , %s  , result:%s", dir, dir.delete()));return;} else {File[] files = dir.listFiles();for (File file : files) {deleteAll(file);}}ApiLogger.info(String.format("delete dir , %s  , result:%s", dir, dir.delete()));}/*** 将byte数组写入文件** @param path* @param content* @throws IOException*/public static void writeFile(String path, byte[] content) throws IOException {try {File f = new File(path);if (!f.exists()) {f.mkdirs();}FileOutputStream fos = new FileOutputStream(path);fos.write(content);fos.close();} catch (IOException e) {ApiLogger.error(String.format("when hls upload  , writeFile , the error occured:%s", e.getMessage()), e);}}/*** 写入到文件** @param file*/public static void writeToFile(File file, String content) throws Exception {Writer out = null;try {out = new FileWriter(file);out.write(content);} catch (IOException e) {ApiLogger.error(String.format("when hls upload  , write to file , the error occured:%s", e.getMessage()), e);} finally {if (out != null) {out.close();}}}/*** 将文本文件中的内容读入到buffer中** @param buffer   buffer* @param filePath 文件路径* @throws IOException 异常* @author cn.outofmemory* @date 2013-1-7*/public static void readToBuffer(StringBuffer buffer, String filePath) throws IOException {InputStream is = new FileInputStream(filePath);String line; // 用来保存每行读取的内容BufferedReader reader = new BufferedReader(new InputStreamReader(is));line = reader.readLine(); // 读取第一行while (line != null) { // 如果 line 为空说明读完了buffer.append(line); // 将读到的内容添加到 buffer 中buffer.append("\n"); // 添加换行符line = reader.readLine(); // 读取下一行}reader.close();is.close();}/*** 读取文本文件内容** @param filePath 文件所在路径* @return 文本内容* @throws IOException 异常* @author cn.outofmemory* @date 2013-1-7*/public static String readFile(String filePath) throws IOException {StringBuffer sb = new StringBuffer();FileUtil.readToBuffer(sb, filePath);return sb.toString();}/*** 读文件*/public static byte[] readFileFromDiskCache(File file) {byte[] buffer = null;try {buffer = new byte[(int) (file.length())];BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));bis.read(buffer);bis.close();} catch (Exception e) {ApiLogger.error("readFileFromDiskCache error, file = " + file.getName(), e);} finally {}return buffer;}/*** 读文件*/public static byte[] readFileFromDiskCache(String filename) {byte[] buffer = null;try {File file = new File(filename);if (!file.exists())return null;buffer = new byte[(int) (file.length())];BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));bis.read(buffer);bis.close();} catch (Exception e) {ApiLogger.error("readFileFromDiskCache error, file = " + filename, e);} finally {}return buffer;}/*** byte数组转换成16进制字符串** @param src* @return*/public static String bytesToHexString(byte[] src) {StringBuilder stringBuilder = new StringBuilder();if (src == null || src.length <= 0) {return null;}for (int i = 0; i < src.length; i++) {int v = src[i] & 0xFF;String hv = Integer.toHexString(v);if (hv.length() < 2) {stringBuilder.append(0);}stringBuilder.append(hv);}return stringBuilder.toString();}/*** 根据文件流判断图片类型** @return jpg/png/gif/bmp*/public static String getPicType(byte imageByte[]) {// 读取文件的前几个字节来判断图片格式byte[] b = new byte[4];try {System.arraycopy(imageByte, 0, b, 0, 4);String type = bytesToHexString(b).toUpperCase();if (type.contains("FFD8FF")) {return FileTypeEnums.JPG.name();} else if (type.contains("89504E47")) {return FileTypeEnums.PNG.name();} else if (type.contains("47494638")) {return FileTypeEnums.GIF.name();} else if (type.contains("424D")) {return FileTypeEnums.BMP.name();} else {return FileTypeEnums.UNKNOWN.name();}} catch (Exception e) {e.printStackTrace();}return "";}public static FileTypeInfo getFileType(byte[] bytes) {return getFileType(bytes, 8);}public static FileTypeInfo getFileType(byte[] bytes, int length) {// 读取文件的前几个字节来判断图片格式byte[] b = new byte[length];try {System.arraycopy(bytes, 0, b, 0, length);String hex = bytesToHexString(b).toUpperCase();for (FileTypeEnums typeEnum : FileTypeEnums.values()) {if (hex.contains(typeEnum.getHex())) {return new FileTypeInfo(typeEnum, hex);}}} catch (Exception e) {ApiLogger.error("[getFileType] error=", e);}return new FileTypeInfo(FileTypeEnums.UNKNOWN, "");}public static boolean isAllowedImage(FileTypeEnums enums) {return ALLOW_IMAGE.contains(enums);}public static boolean isAllowedImage(byte[] bytes) {return assertAllowed(bytes, ALLOW_IMAGE);}public static boolean assertAllowed(byte[] bytes, FileTypeEnums... allowedExtension) {return assertAllowed(bytes, Arrays.asList(allowedExtension));}/*** 文件上传校验** @param bytes            上传的文件二进制流* @param allowedExtension 允许上传的文件后缀集合*/public static boolean assertAllowed(byte[] bytes, List<FileTypeEnums> allowedExtension) {// 读取文件的前几个字节来判断图片格式byte[] b = new byte[8];try {System.arraycopy(bytes, 0, b, 0, 8);String type = bytesToHexString(b).toUpperCase();ApiLogger.info("[assertAllowed] type=" + type);for (FileTypeEnums typeEnum : allowedExtension) {if (type.contains(typeEnum.getHex())) {return true;}}return false;} catch (Exception e) {ApiLogger.error("[assertAllowed] error=", e);}return false;}/*** 判断MIME类型是否是允许的MIME类型** @param extension* @param allowedExtension* @return*/public static boolean isAllowedExtension(String extension, String[] allowedExtension) {for (String str : allowedExtension) {if (str.equalsIgnoreCase(extension)) {return true;}}return false;}public static void main(String[] args) {byte image1[] = readFileFromDiskCache("/Users/marion/data/image/1.jpg");byte image2[] = readFileFromDiskCache("/Users/marion/data/image/2.jpeg");byte image3[] = readFileFromDiskCache("/Users/marion/data/image/3.png");byte image4[] = readFileFromDiskCache("/Users/marion/data/image/4.webp");byte image5[] = readFileFromDiskCache("/Users/marion/data/image/5.heif");byte image6[] = readFileFromDiskCache("/Users/marion/data/image/6.bmp");byte image7[] = readFileFromDiskCache("/Users/marion/data/image/7.webp");String type1 = getPicType(image1);String type2 = getPicType(image2);String type3 = getPicType(image3);String type4 = getPicType(image4);String type5 = getPicType(image5);String type6 = getPicType(image6);String type7 = getPicType(image7);System.out.println("type1=" + type1); // jpgSystem.out.println("type2=" + type2); // jpgSystem.out.println("type3=" + type3); // pngSystem.out.println("type4=" + type4); // 52494646D8410000System.out.println("type5=" + type5); // 0000001866747970System.out.println("type6=" + type6); // bmpSystem.out.println("type7=" + type7); // bmp}public static final List<FileTypeEnums> ALLOW_IMAGE = Arrays.asList(FileTypeEnums.JPG,FileTypeEnums.PNG,FileTypeEnums.GIF,FileTypeEnums.BMP,FileTypeEnums.WEBP);public enum FileTypeEnums {/*** hex: 二进制文件头*/JPG("FFD8FFE0", "jpg"),PNG("89504E47", "png"),GIF("47494638", "gif"),WEBP("52494646", "webp"),TIF("49492A00", "tif"),BMP("424D", "bmp"),PSD("38425053", "psd"),XML("3C3F786D6C", "xml"),HTML("68746D6C3E", "html"),DOC("D0CF11E0", "doc"),MDB("5374616E64617264204A", "mdb"),PDF("255044462D312E", "pdf"),DOCX("504B0304", "docx"),RAR("52617221", "rar"),AVI("41564920", "avi"),HEIF("66747970", "heif"),UNKNOWN("", "");String hex;String suffix;FileTypeEnums(String hex, String suffix) {this.hex = hex;this.suffix = suffix;}public String getHex() {return hex;}public String getSuffix() {return suffix;}}public static class FileTypeInfo {private FileTypeEnums type;private String fileHex;public FileTypeInfo() {}public FileTypeInfo(FileTypeEnums type, String fileHex) {this.type = type;this.fileHex = fileHex;}public FileTypeEnums getType() {return type;}public void setType(FileTypeEnums type) {this.type = type;}public String getFileHex() {return fileHex;}public void setFileHex(String fileHex) {this.fileHex = fileHex;}}}

参考资料

大聪明教你学Java | 比校验文件后缀名更靠谱的上传文件校验方式 —— 文件魔数校验_不肯过江东丶的博客-CSDN博客_魔数校验

HEIF图片格式详解 - 知乎

常用文件的二进制头信息

Convertio — 文件转换器

16进制转换,16进制转换文本字符串,在线16进制转换 | 在线工具

Java中16进制与字符串之间的相互转换 - 编程世界里晃荡 - 博客园

更多推荐

【图片服务】校验上传图片真实格式、伪后缀校验、文件魔术校验

本文发布于:2024-02-13 22:07:51,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1760871.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:后缀   上传图片   魔术   真实   格式

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!