博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
读取16进制文件和校验图片格式的问题。 文件名后缀
阅读量:5273 次
发布时间:2019-06-14

本文共 2728 字,大约阅读时间需要 9 分钟。

概要:

  前段时间,要做这样一个校验:当不符合要求的文件,通过修改文件后缀名后,仍然不允许上传。

我想这是大家经常会遇到的一个校验问题。我才用的办法是:用16进制读取文件头部(不妨成为head),比较head和常见文件头部16进制编码,进行判断。

我个人认为,这个校验方法有弊端,例如当两中不同的文件的文件头编码一样时,一种符合上传要求,一种不符合上传要求,起不到校验功能,例如office 2007和zip。

但是这个方法还是很实用的,毕竟文件头一样的不同文件总是不多的,而且在网站上传是碰到的就更少了,对图片校验还是非常有效的,目前没发现常见图片文件头相同的现象。

注明:office 2007和zip,一般都是允许的上传文件格式,“你可以上传ppt/pptx, doc/docx, ... ,多个文件可以压缩成zip,rar上传”,所以不用担心这个情况了。同文件头编码总是不多的!

ZIP Archive (zip),文件头:504B0304 MS Word/Excel (xlsx pptx docx),文件头: 504B0304 当 docx 没有内容时,没有找到文件头;当它有内容时,它有文件头:504B0304

 

文章顺序:

1.常见文件后缀名

2.我的代码

3.参考的资料

 

1.常见文件后缀名

参见:http://www.cnblogs.com/xxchao/p/3965005.html

2.我的代码

 代码有什么改进的方法,求高手指教一二,谢谢。

。。。。InputStream in = fileItem.getInputStream();                    String head = readOriginal2Hex(in, 4).toUpperCase();                    if(null == head || "".equals(head)){                        msgBean.setMsg("请上传.jpg/.jpeg/.png/.gif/.bmp的格式").setMsgCode(MsgBean.MsgCode.FAILURE);                        return msgBean;                    }                   /* 文件开头的标志字符                    JPEG (jpg),文件头:FFD8FF                     PNG (png),文件头:89504E47                     GIF (gif),文件头:47494638                    Windows Bitmap (bmp),文件头:424D                      */    if("47494638".equals(head) || "89504E47".equals(head) || "FFD8FF".equals(head.substring(0, 6)) || "424D".equals(head.substring(0, 4))){。。。。 //做你要的业务}                                        。。。。。/**     * 读取文件开头n个字节,为16进制String     * @param InputStream     * @param int     * @return String     * @throws IOException     */    public String readOriginal2Hex(InputStream in, int n) throws IOException{        //FileInputStream fin = new FileInputStream(new File(RO_HOME + BAK_FILE));        StringWriter sw = new StringWriter();        int len = 1;        byte[] temp = new byte[len]; //字节,字节(Byte)是计算机信息技术用于计量存储容量和传输容量的一种计量单位,1个字节等于8位二进制。                //16进制转化模块        for(int i = 0; (in.read(temp, 0, len)!=-1) && (i < n); i++){            if(temp[0] > 0xf && temp[0] <= 0xff){ // 10~ff                sw.write(Integer.toHexString(temp[0]));            }else if(temp[0] >= 0x0 && temp[0] <= 0xf){  // 0~f                //对于只有一位的16进制数前面补“0”                sw.write("0" + Integer.toHexString(temp[0]));                            }else{                //对于int<0的位转化为16进制的特殊处理,因为Java没有Unsigned int,所以这个int可能为负数                sw.write(Integer.toHexString(temp[0]).substring(6));  /* 对于为什么是从6开始截,这涉及内存溢出的知识,我的解释是:java调试跟踪查到 -1   ffffffff,-40  ffffffd8,-31  ffffffe1 ,一个字节8位二进制,最大255 = ff,一个16进制数由4位二进制数转化得来,这里无符号数才能到达255,下次在说理由。。 有知道的说下。。  */            }        }                return sw.toString();    }

 

 

3.参考的资料

http://blog.csdn.net/cdtdx/article/details/1529804

 

转载于:https://www.cnblogs.com/xxchao/p/3982031.html

你可能感兴趣的文章
我工作这十年-世界在变化
查看>>
log4j2 不使用配置文件,动态生成logger对象
查看>>
[IOI2014]holiday假期(分治+主席树)
查看>>
python的上下文管理(contextlib)(2)
查看>>
mysql安装
查看>>
运算符有感
查看>>
设置dataGridView单元格颜色、字体、ToolTip、字体颜色
查看>>
wx-charts 微信小程序图表 -- radarChart C# .net .ashx 测试
查看>>
对项目重命名
查看>>
Scrapy框架简介及小项目应用
查看>>
tkinter学习三
查看>>
CentOS自带定时任务crontab
查看>>
基因组拼接中常见的名词解释
查看>>
##CS3动画效果
查看>>
nginx 配置 http重定向到https
查看>>
Linux vi/vim
查看>>
JS 设置复选框的选中与取消选中
查看>>
【京东咚咚架构演进】-- 好文收藏
查看>>
【BZOJ 3155】Preprefix sum(树状数组)
查看>>
【洛谷 2430】严酷的训练
查看>>