欢送大家搜寻“小猴子的技术笔记”关注我的公众号,有问题能够及时和我交换。
在日常的生存中,咱们必定都经验过相似这样的场景:报名考试上传图片,网站要求的是上传的照片不能大于多少,而且要求是“.jpg”的格局。
于是你高高兴兴的把本人最丑陋的照片上传上去了,然而网站却提醒你照片格局不正确,让你从新上传。这个时候心田不晓得有多少纳闷涌上心头(其实是草泥马在奔流)我的照片明明就是“.jpg”结尾的,而且大小也符合规范,为啥就不行呢?
咱们通常的会认为(Windows电脑状况下,Mac不晓得,毕竟我没有图片)“.jpg”图片结尾的就肯定是符合规范的“JPG”文件类型。其实一开始我也是这样认为的,直到前几天,我在对接我的项目的时候踩了一个大坑,很大的坑!
我对接的我的项目要求的是图片是“JPG”类型的文件,并且通过base64进行编码之后要以"/9j"结尾的文件。于是我就把我电脑上保留的看似符合规范的图片上传上去了,后果就是一堆报错信息。于是我再次尝试,换一些其余的图片进行测试,发现有的就好使,有的就不好使。说实话,我的心田解体了!那种感觉你懂得图片
回到家之后我思来想去就是不晓得为什么要求什么"/9j"结尾的?我关上了百度,输出了关键词“/9j”之后,呵呵!我笑了,都是些什么?齐全跟我的问题不着边!
什么玩意?这到底是什么玩意?居然连弱小的百度都没有给出后果!就这样,我搜寻到了凌晨12点......
扛不住了,我就去睡觉了。然而躺在床上我辗转难眠,关上手机持续各种搜寻着......忽然!我看了一个对于电脑图片文件头信息解析的文章!一道灵光从我脑门上闪过。于是我起床,默默关上了电脑,关上了百度......
原来电脑在存储的时候是存储了图片的根本信息的,比方图片是什么类型的,图片的宽低等根本信息,这些个根本信息叫做图片头信息。好吧!原谅我的无知,已经的我天真的认为是依照文件后缀名辨别的呢。
咱们应晓得,图片在计算机中存储是一个一个的像素点,最底层也是二进制文件,所以须要文件头来保留文件信息。经查找材料,我找到如下对图片不同格局的文件头标识信息(16进制标识):
1.BMP 文件头标识 (2 bytes) 42 4D
2.PNG 文件头标识 (8 bytes) 89 50 4E 47 0D 0A 1A 0A
3.GIF 文件头标识 (6 bytes) 47 49 46 38 39(37) 61
4.JPEG/JPG 文件头标识 (2 bytes): FF D8 (SOI) (JPEG 文件标识)
于是我在电脑上保留了一个为“.jpg”后缀结尾的图片,而后应用UE这个弱小的工具关上,果然不出我所料,看看这个文件的内容信息。
不出意外的话,你必定看不懂这些货色,因为这些是16进制文件。然而重要的我曾经给你标注进去了,那就是“FF D8”。
在这里我给大家略微简略科普下base64的编码规定:如果咱们有个“hello”这样的关键字进行base64编码,须要先把“hello”转换成二进制,也就是"110100011001011101100110 11001101111"。我这里给了一个ASCII表,这里对应的是10进制的,须要把十进制转化成2进制的。
对于base64 有个规定就是,一个字符转换之后如果位数不为8位,须要在高位补0,而后再6位截取,最初不够6位的,低位补0。而后把宰割后的2进制转换成10进制并对照base64编码表进行解析。那么上述的“hello”的解析过程就如下:
所以“hello”base64编码之后的最终后果就是“aGVsbG8=”。兴许你会纳闷,为什么多了个“=” 这个其实是base64的规定,编码结束之后主动增加一个或两个“=”。
那么再回到“FF D8”,jpg文件的标识头,他通过base64转码之后是什么呢?
谢天谢地,可算搞明确为什么是“/9j”结尾的了。其实还有另外一种形式疾速查看是不是jpg格式文件。咱们能够应用记事本的形式关上一个jpg文件。
关上之后,你必定还是看不懂这些货色,然而重要的我曾经给你标注进去了,那就是“JFIF”,这个是一个很重要的标识,所谓的“JFIF”就是"JPEG File Interchonge Format"即JPEG文件替换格局。
为了还原我之前明明是“.jpg”后缀的文件,然而辨认失败的问题。咱们把一个格局为“.png”图片,通过改后缀名的形式,改成“.jpg”。而后也用记事本关上查看文件的内容。
能够看到,并不是“JFIF”,因而这并不是一个jpg文件,所以上传无奈辨认。
带着问题去睡觉,果然是睡不着的!通过这次的经验,我晓得了base64的编码原理,明确了文件在电脑中存储并不是靠简简单单的后缀名来辨别的,而是有文件头信息的。文件到底是一个什么文件,还是要靠文件头信息来决定的。所以,你当前的程序判断文件类型千万不要仅仅判断后缀名就完事了哦!