如何更好的判断系统上传文件是指定文件类型--文件魔术数字
来源:互联网 发布:淘宝女包手提包 编辑:程序博客网 时间:2024/05/11 02:29
理论介绍
这里所说的表示不同文件类型的魔术数字,指定是文件的最开头的几个用于唯一区别其它文件类型的字节,有了这些魔术数字,我们就可以很方便的区别不同的文件,这也使得编程变得更加容易,因为我减少了我们用于区别一个文件的文件类型所要花费的时间。
比如,一个JPEG文件,它开头的一些字节可能是类似这样的”ffd8 ffe0 0010 4a46 4946 0001 0101 0047 ……JFIF…..G“,这里”ffd8“就表示了这个文件是一个JPEG类型的文件,”ffe0“表示这是JFIF类型结构。
以下例出的是一些我们常见的文件类型,以及它用于判断这种文件的类型的几个开始字节及所对尖的ASCII数字:
图片文件
压缩文件
存档文件
可执行文件
其它文件
java实现(图片类型判断)
使用魔术数字判断
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class ImageTypeCheck { 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++) { // byte转int int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } public static void main(String[] args) throws IOException { String imagePath = "c:/favicon.png"; File image = new File(imagePath); InputStream is = new FileInputStream(image); byte[] bt = new byte[2]; is.read(bt); System.out.println(bytesToHexString(bt)); } }
使用图片长宽判断
如果能够正常的获取到一张图片的宽高属性,那肯定这是一张图片,因为非图片文件我们是获取不到它的宽高属性的,以下是用于获取根据是否可以获取到图片宽高属性来判断这是否一张图片的JAVA代码:
/** * 通过读取文件并获取其width及height的方式,来判断判断当前文件是否图片,这是一种非常简单的方式。 * * @param imageFile * @return */ public static boolean isImage(File imageFile) { if (!imageFile.exists()) { return false; } Image img = null; try { img = ImageIO.read(imageFile); if (img == null || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) { return false; } return true; } catch (Exception e) { return false; } finally { img = null; } }
好了,我们终于判断出一个文件是否图片了,可是如果是在一个可以正常浏览的图片文件中加入一些非法的代码呢:
这就是在一张正常的图片末尾增加的一些iframe代码,我曾经尝试过单独打开这张图片,也将这张图片放于网页上打开,虽然这样都不会被执行,但并不代表插入其它的代码也并不会执行,杀毒软件(如AVAST)对这种修改是会报为病毒的。
那我们要如何预防这种东西,即可以正常打开,又具有正确的图片文件扩展名,还可以获取到它的宽高属性?呵,我们这个时候可以对这个图片进地重写,给它增加水印或者对它进行resize操作,这样新生成的图片就不会再包含这样的恶意代码了,以下是一个增加水印的JAVA实现:
增加水印的JAVA实现
/** * 添加图片水印 * * @param srcImg 目标图片路径,如:C:\\kutuku.jpg * @param waterImg 水印图片路径,如:C:\\kutuku.png * @param x 水印图片距离目标图片左侧的偏移量,如果x<0, 则在正中间 * @param y 水印图片距离目标图片上侧的偏移量,如果y<0, 则在正中间 * @param alpha 透明度(0.0 -- 1.0, 0.0为完全透明,1.0为完全不透明) * @throws IOException */ public final static void addWaterMark(String srcImg, String waterImg, int x, int y, float alpha) throws IOException { // 加载目标图片 File file = new File(srcImg); String ext = srcImg.substring(srcImg.lastIndexOf(".") + 1); Image image = ImageIO.read(file); int width = image.getWidth(null); int height = image.getHeight(null); // 将目标图片加载到内存。 BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g = bufferedImage.createGraphics(); g.drawImage(image, 0, 0, width, height, null); // 加载水印图片。 Image waterImage = ImageIO.read(new File(waterImg)); int width_1 = waterImage.getWidth(null); int height_1 = waterImage.getHeight(null); // 设置水印图片的透明度。 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); // 设置水印图片的位置。 int widthDiff = width - width_1; int heightDiff = height - height_1; if (x < 0) { x = widthDiff / 2; } else if (x > widthDiff) { x = widthDiff; } if (y < 0) { y = heightDiff / 2; } else if (y > heightDiff) { y = heightDiff; } // 将水印图片“画”在原有的图片的制定位置。 g.drawImage(waterImage, x, y, width_1, height_1, null); // 关闭画笔。 g.dispose(); // 保存目标图片。 ImageIO.write(bufferedImage, ext, file); }
整理参考:
http://blog.csdn.net/fenglibing/article/details/7733496
http://blog.csdn.net/fenglibing/article/details/7728275
- 如何更好的判断系统上传文件是指定文件类型--文件魔术数字
- input 文件上传指定特定的文件类型
- php上传文件文件类型的判断方法
- 文件上传时只接收指定的文件类型
- 不同文件类型的魔术数字
- 上传文件的文件类型及大小的判断
- struts2文件上传中,如何限制上传的文件类型
- PHP根据文件头信息准确判断上传的文件类型
- 文件上传过程中判断文件类型
- 如何判断上传文件类型
- struts2如何获取上传文件的文件名和文件类型
- 如何判断上传的文件类型??是先判断再上传还是先上传再判断?真实的文件类型是什么样的?
- 表示不同文件类型的魔术数字
- 表示不同文件类型的魔术数字
- 表示不同文件类型的魔术数字
- 表示不同文件类型的魔术数字
- 表示不同文件类型的魔术数字【整理】
- 表示不同文件类型的魔术数字
- 深入理解Java Annotation
- windows申请免费SSL证书-Let's Encrypt
- 16-3-3代码
- Objective-c中关于UI主线程与正向传值冲突的解决办法
- Asp.net MVC Session过期异常的处理
- 如何更好的判断系统上传文件是指定文件类型--文件魔术数字
- Kerberos认证流程详解
- 开学了
- 用GPUImage做自己的滤镜
- Objective-C 属性特性(assign , retain , copy , readonly , readwrite , atomic , nonatomic)专业App,微信,网站开发 麻城
- oracle-存储函数
- servlet与jsp的生命周期
- Apache Thrift - 可伸缩的跨语言服务开发框架
- Java ClassLoader基础及加载不同依赖 Jar 中的公共类