通过判断魔数来判断文件类型

2019-01-16  本文已影响0人  孟媛的笔记
import org.apache.commons.lang3.StringUtils;
 
/**
 * 文件类型与对应的文件魔数枚举类 
 *
 */
public enum FileTypeEnum { 
    
    /** JPEG  (jpg)*/
    JPEG("JPG", "FFD8FF"),
 
    /** PNG */
    PNG("PNG", "89504E47"),
 
    /** GIF */
    GIF("GIF", "47494638"),
  
    /** TIFF (tif)  */
    TIFF("TIF", "49492A00"),
 
    /** Windows bitmap (bmp) */
    BMP("BMP","424D"),
    
    BMP_16("BMP","424D228C010000000000"), //16色位图(bmp) 
    
    BMP_24("BMP","424D8240090000000000"), //24位位图(bmp)  
    
    BMP_256("BMP","424D8E1B030000000000"), //256色位图(bmp)     
 
    /** CAD  (dwg) */
    DWG("DWG", "41433130"),
 
    /** Adobe photoshop  (psd)*/
    PSD("PSD", "38425053"),
 
    /** Rich Text Format  (rtf)*/
    RTF("RTF", "7B5C727466"),
 
    /** XML */
    XML("XML", "3C3F786D6C"),
 
    /** HTML (html)*/
    HTML("HTML", "68746D6C3E"),
    
    /** Email [thorough only] (eml)*/
    EML("EML", "44656C69766572792D646174653A"),  
    
    /** Outlook Express (dbx) */
    DBX("DBX", "CFAD12FEC5FD746F "),
 
    /** Outlook (pst)*/
    PST("", "2142444E"),
 
    /** doc;xls;dot;ppt;xla;ppa;pps;pot;msi;sdw;db */
    OLE2("OLE2", "0xD0CF11E0A1B11AE1"),
 
    /** Microsoft Word/Excel 注意:word 和 excel的文件头一样 */
    XLS("XLS", "D0CF11E0"),
    
    /** Microsoft Word/Excel 注意:word 和 excel的文件头一样 */
    DOC("DOC", "D0CF11E0"),
    
    /** Microsoft Word/Excel 2007以上版本文件 注意:word 和 excel的文件头一样 */
    DOCX("DOCX", "504B0304"),  
 
    /** Microsoft Word/Excel 2007以上版本文件 注意:word 和 excel的文件头一样 504B030414000600080000002100*/
    XLSX("XLSX", "504B0304"), 
 
    /** Microsoft Access (mdb)*/
    MDB("MDB", "5374616E64617264204A"),
 
    /** Word Perfect (wpd)*/
    WPB("WPB", "FF575043"),
 
    /** Postscript */
    EPS("EPS", "252150532D41646F6265"),
 
    /** Postscript */
    PS("PS", "252150532D41646F6265"),
 
    /** Adobe Acrobat (pdf)  */
    PDF("PDF", "255044462D312E"),
    
    /** Quicken (qdf) */
    QDF("qdf", "AC9EBD8F"),
    
    /** QuickBooks Backup (qdb) */
    QDB("qbb", "458600000600"),
    
    /** Windows Password  (pwl)*/
    PWL("PWL", "E3828596"),
 
    /** ZIP Archive */
    ZIP("", "504B0304"),
 
    /** ARAR Archive */
    RAR("", "52617221"),
 
    /** WAVE (wav) */
    WAV("WAV", "57415645"),
 
    /** AVI */
    AVI("AVI", "41564920"),
 
    /** Real Audio (ram)*/
    RAM("RAM", "2E7261FD"),
 
    /** Real Media (rm) rmvb/rm相同  */
    RM("RM", "2E524D46"),
    
    /** Real Media (rm) rmvb/rm相同  */
    RMVB("RMVB", "2E524D46000000120001"),  
    
    /** MPEG (mpg)  */
    MPG("MPG", "000001BA"),
    
    /** Quicktime  (mov)*/
    MOV("MOV", "6D6F6F76"),
 
    /** Windows Media (asf) */
    ASF("ASF", "3026B2758E66CF11"),
 
    /** ARJ Archive */
    ARJ("ARJ", "60EA"),
 
    /** MIDI (mid) */
    MID("MID", "4D546864"),
    
    /** MP4 */  
    MP4("MP4", "00000020667479706D70"), 
    
    /** MP3 */  
    MP3("MP3", "49443303000000002176"),  
    
    /** FLV */  
    FLV("FLV", "464C5601050000000900"), 
    
    /** 1F8B0800000000000000 */
    GZ("GZ", "1F8B08"),
    
    /** CSS */ 
    CSS("CSS", "48544D4C207B0D0A0942"),
    
    /**  JS */  
    JS("JS", "696B2E71623D696B2E71"), 
     
    /**  Visio */  
    VSD("VSD", "d0cf11e0a1b11ae10000"),
    
    /** WPS文字wps、表格et、演示dps都是一样的 */  
    WPS("WPS", "d0cf11e0a1b11ae10000"),
    
    /** torrent */  
    TORRENT("TORRENT", "6431303A637265617465"), 
    
    /** JSP Archive */  
    JSP("JSP", "3C2540207061676520"),  
    
    /** JAVA Archive */  
    JAVA("JAVA", "7061636B61676520"), 
    
    /** CLASS Archive */  
    CLASS("CLASS", "CAFEBABE0000002E00"), 
    
    /** JAR Archive */  
    JAR("JAR", "504B03040A000000"), 
    
    /** MF Archive */  
    MF("MF", "4D616E69666573742D56"),
 
    /** EXE Archive */  
    EXE("EXE", "4D5A9000030000000400"), 
 
    /** ELF Executable */  
    ELF("ELF", "7F454C4601010100"), 
 
    /** Lotus 123 v1 */  
    WK1("WK1", "2000604060"),
    
    /** Lotus 123 v3 */  
    WK3("WK3", "00001A0000100400"),
    
    /** Lotus 123 v5 */  
    WK4("WK4", "00001A0002100400"), 
 
    /** Lotus WordPro v9 */  
    LWP("LWP", "576F726450726F"), 
    
    /** Sage(sly.or.srt.or.slt;sly;srt;slt) */  
    SLY("SLY", "53520100"), 
    
    /** CHM Archive */  
   /* CHM("CHM", "49545346030000006000"),  
    INI("INI", "235468697320636F6E66"), 
    SQL("SQL", "494E5345525420494E54"), 
    BAT("BAT", "406563686F206f66660D"),  
    PROPERTIES("", "6C6F67346A2E726F6F74"), 
    MXP("", "04000000010000001300"),  */
    
    NOT_EXITS_ENUM("", "");
    
    //文件类型对应的名称
    private String fileTypeName;
    
    //文件类型对应的魔数
    private String magicNumberCode;
    
    private FileTypeEnum(String fileTypeName, String magicNumberCode) {
        this.fileTypeName = fileTypeName;
        this.magicNumberCode = magicNumberCode;
    } 
     
    public String getFileTypeName() {
        return fileTypeName;
    } 
 
    public String getMagicNumberCode() {
        return magicNumberCode;
    }
 
 
    /**
     * 根据文件类型获取文件类型魔数编码
     * 默认返回标准件
     * @param magicNumberCode - 文件类型魔数编码
     * @return
     */
    public static FileTypeEnum getByMagicNumberCode(String magicNumberCode) {
        if (StringUtils.isNotBlank(magicNumberCode)) {
            for (FileTypeEnum type : values()) { 
                if (magicNumberCode.toUpperCase().startsWith(type.getMagicNumberCode())) {
                    return type; 
                } 
            } 
        }
        
        return FileTypeEnum.NOT_EXITS_ENUM;
    }
    
    /**
     * 根据文件类型后缀名获取枚举
     * 
     * @param fileTypeName - 文件类型后缀名
     * @return
     */
    public static FileTypeEnum getByFileTypeName(String fileTypeName) { 
        if (StringUtils.isNotBlank(fileTypeName)) {
            for (FileTypeEnum type : values()) {
                if (type.getFileTypeName().equals(fileTypeName)) {
                    return type; 
                } 
            }
        }
        return FileTypeEnum.NOT_EXITS_ENUM;
    }
  
}
  
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
 
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
 
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
  
/**
 * 通过文件魔数来判断文件类型
 * 可以最大量避免通过后缀名来判断文件类型的漏洞
 * 
 * @author 000125
 *
 */
public class FileTypeUtils {   
    private static final Logger LOGGER = LoggerFactory.getLogger(FileTypeUtils.class);
    
    /**  
     * 获取图片文件实际类型,若不是图片则返回null]
     * @param file 
     * @return fileType  
     */  
    public final static String getImageFileType(File file) {  
        if (isImage(file)) {
            try {
                ImageInputStream iis = ImageIO.createImageInputStream(file);
                Iterator<ImageReader> iter = ImageIO.getImageReaders(iis);
                if (!iter.hasNext()) {
                    return null;
                }
                ImageReader reader = iter.next();
                iis.close();
                return reader.getFormatName();
            } catch (IOException e) {
                return null;
            } catch (Exception e) {
                return null;
            }
        }
        return null;
    }  
  
    /**   
     * 获取文件类型,包括图片,若格式不是已配置的,则返回null
     * @param file 
     * @return fileType  
     */  
    public final static String getFileByFile(File file) {  
        String filetype = null;  
        byte[] b = new byte[50];  
        try {  
            InputStream is = new FileInputStream(file);  
            is.read(b);  
            filetype = getFileTypeByStream(b);  
            is.close();  
        } catch (FileNotFoundException e) {  
            e.printStackTrace();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
        return filetype;  
    }  
      
    /** 
     * 通过数据流(二进制数据)判断文件类型
     * @param b 
     * @return fileType  
     */  
    public final static String getFileTypeByStream(byte[] b) {  
        String magicNumberCode = String.valueOf(getFileHexString(b));  
        
        if (StringUtils.isBlank(magicNumberCode)) { 
            return FileTypeEnum.getByMagicNumberCode(magicNumberCode.toUpperCase()).getFileTypeName();
            
        }
        return FileTypeEnum.NOT_EXITS_ENUM.getFileTypeName();  
    }  
      
    /** 
     * isImage,判断文件是否为图片
     * @param file
     * @return true 是 | false 否 
     */
    public static final boolean isImage(File file){
        boolean flag = false;
        try {
            BufferedImage bufreader = ImageIO.read(file);
            int width = bufreader.getWidth();
            int height = bufreader.getHeight();
            if(width==0 || height==0){
                flag = false;
            }else {
                flag = true;
            }
        } catch (IOException e) {
            flag = false;
        }catch (Exception e) {
            flag = false;
        }
        return flag;
    }
    
   
    /**
     * 通过文件路径判断文件类型
     * @param path
     * @return
     * @throws IOException
     */
    public static FileTypeEnum getFileTypeByPath(String path) {
        // 获取文件头
        String magicNumberCode = null;
        try {
            magicNumberCode = getFileHeader(path);
        } catch (Exception e) { 
            e.printStackTrace();
            return FileTypeEnum.NOT_EXITS_ENUM;
        }
 
        if (StringUtils.isBlank(magicNumberCode)) { 
            return FileTypeEnum.getByMagicNumberCode(magicNumberCode.toUpperCase());
            
        }
 
        return FileTypeEnum.NOT_EXITS_ENUM;
    }
 
    
    /**
     * 通过文件路径获取文件头(即文件魔数)
     * @param path
     * @return
     * @throws IOException
     */
    public static String getFileHeader(String path) throws Exception {
        byte[] b = new byte[28];
        InputStream inputStream = null;
 
        try {
            inputStream = new FileInputStream(path);
            inputStream.read(b, 0, 28);
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
 
        return getFileHexString(b);
    }
    
    /**   
     * 把文件二进制流转换成十六进制数据
     * @param b 
     * @return fileTypeHex  
     */  
    public final static String getFileHexString(byte[] b) {  
        StringBuilder builder = new StringBuilder();  
        if (b == null || b.length <= 0) {  
            return null;  
        }  
        
        for (int i = 0; i < b.length; i++) {  
            int v = b[i] & 0xFF;  
            String hv = Integer.toHexString(v);  
            if (hv.length() < 2) {  
                builder.append(0);  
            }  
            builder.append(hv);  
        }  
        return builder.toString();  
    }  
}
上一篇下一篇

猜你喜欢

热点阅读