http://www.nowamagic.net/librarys/veda/detail/836
文件签名一般都在文件的头部,如果你用十六进制方式查看文件,你就可以看到文件的一些签名信息。如用uestudio以十六进制方式查看zip格式的文件,其文件内容头部有50 4B 03 04这样的十六进制信息。同理jpg文件状况有FF D8 FF E0 xx xx 4A 46这样的十六进制信息,其实这此十六进制都是表示一些特殊字条。
php怎么样验证文件类型?先来看一个简单的方法:
01 | function checkFileType($fileName){ |
02 | $file = fopen($fileName, "rb"); |
03 | $bin = fread($file, 2); //只读2字节 |
04 | fclose($file); |
05 | // C为无符号整数,网上搜到的都是c,为有符号整数,这样会产生负数判断不正常 |
06 | $strInfo = @unpack("C2chars", $bin); |
07 | $typeCode = intval($strInfo['chars1'].$strInfo['chars2']); |
08 | $fileType = ''; |
09 |
10 | switch( $typeCode ) |
11 | { |
12 | case '255216': |
13 | return $typeCode. ' : ' .'jpg'; |
14 | break; |
15 | case '7173': |
16 | return $typeCode. ' : ' .'gif'; |
17 | break; |
18 | case '13780': |
19 | return $typeCode. ' : ' .'png'; |
20 | break; |
21 | case '6677': |
22 | return $typeCode. ' : ' .'bmp'; |
23 | break; |
24 | case '7790': |
25 | return $typeCode. ' : ' .'exe'; |
26 | break; |
27 | case '7784': |
28 | return $typeCode. ' : ' .'midi'; |
29 | break; |
30 | case '8297': |
31 | return $typeCode. ' : ' .'rar'; |
32 | break; |
33 | default: |
34 | return $typeCode. ' : ' .'Unknown'; |
35 | break; |
36 | } |
37 | //return $typeCode; |
38 | } |
39 |
40 | $file_name = '11.doc'; |
41 | echo checkFileType($file_name); |
下来提供一个类的实现:
01 | /*通过文件名,获得文件类型* |
02 | *@author chengmo QQ:8292669* |
03 | *@copyright <a href="http://www.cnblogs.com/chengmo">http://www.cnblogs.com/chengmo</a> 2010-10-17 |
04 | *@version 0.1 |
05 | *$filename="d:/1.png";echo cFileTypeCheck::getFileType($filename); 打印:png |
06 | */ |
07 | class cFileTypeCheck |
08 | { |
09 | private static $_TypeList=array(); |
10 | private static $CheckClass=null; |
11 | private function __construct($filename) |
12 | { |
13 | self::$_TypeList=$this->getTypeList(); |
14 | } |
15 | |
16 | /** |
17 | *处理文件类型映射关系表* |
18 | * |
19 | * @param string $filename 文件类型 |
20 | * @return string 文件类型,没有找到返回:other |
21 | */ |
22 | private function _getFileType($filename) |
23 | { |
24 | $filetype="other"; |
25 | if(!file_exists($filename)) throw new Exception("no found file!"); |
26 | $file = @fopen($filename,"rb"); |
27 | if(!$file) throw new Exception("file refuse!"); |
28 | $bin = fread($file, 15); //只读15字节 各个不同文件类型,头信息不一样。 |
29 | fclose($file); |
30 | |
31 | $typelist=self::$_TypeList; |
32 | foreach ($typelist as $v) |
33 | { |
34 | $blen=strlen(pack("H*",$v[0])); //得到文件头标记字节数 |
35 | $tbin=substr($bin,0,intval($blen)); ///需要比较文件头长度 |
36 | |
37 | if(strtolower($v[0])==strtolower(array_shift(unpack("H*",$tbin)))) |
38 | { |
39 | return $v[1]; |
40 | } |
41 | } |
42 | return $filetype; |
43 | } |
44 | |
45 | /** |
46 | *得到文件头与文件类型映射表* |
47 | * |
48 | * @return array array(array('key',value)...) |
49 | */ |
50 | public function getTypeList() |
51 | { |
52 | return array(array("FFD8FFE1","jpg"), |
53 | array("89504E47","png"), |
54 | array("47494638","gif"), |
55 | array("49492A00","tif"), |
56 | array("424D","bmp"), |
57 | array("41433130","dwg"), |
58 | array("38425053","psd"), |
59 | array("7B5C727466","rtf"), |
60 | array("3C3F786D6C","xml"), |
61 | array("68746D6C3E","html"), |
62 | array("44656C69766572792D646174","eml"), |
63 | array("CFAD12FEC5FD746F","dbx"), |
64 | array("2142444E","pst"), |
65 | array("D0CF11E0","xls/doc"), |
66 | array("5374616E64617264204A","mdb"), |
67 | array("FF575043","wpd"), |
68 | array("252150532D41646F6265","eps/ps"), |
69 | array("255044462D312E","pdf"), |
70 | array("E3828596","pwl"), |
71 | array("504B0304","zip"), |
72 | array("52617221","rar"), |
73 | array("57415645","wav"), |
74 | array("41564920","avi"), |
75 | array("2E7261FD","ram"), |
76 | array("2E524D46","rm"), |
77 | array("000001BA","mpg"), |
78 | array("000001B3","mpg"), |
79 | array("6D6F6F76","mov"), |
80 | array("3026B2758E66CF11","asf"), |
81 | array("4D546864","mid")); |
82 | } |
83 | |
84 | |
85 | public static function getFileType($filename) |
86 | { |
87 | if(!self::$CheckClass) self::$CheckClass=new self($filename); |
88 | $class=self::$CheckClass; |
89 | return $class->_getFileType($filename); |
90 | } |
91 | |
92 | } |
93 |
94 | $filename="22.jpg"; |
95 | echo $filename,"t",cFileTypeCheck::getFileType($filename),"rn"; |
96 | $filename="11.doc"; |
97 | echo $filename,"t",cFileTypeCheck::getFileType($filename),"rn"; |
或者可以这么检测:
01 | $filename = '22.jpg'; |
02 | |
03 | $extname = strtolower(substr($filename, strrpos($filename, '.') + 1)); |
04 | echo $extname.'<br />'; |
05 | $file = @fopen($filename, 'rb'); |
06 | if ($file) |
07 | { |
08 | $str = @fread($file, 0x400); // 读取前 1024 个字节 |
09 | echo substr($str, 0, 4); |
10 | @fclose($file); |
11 | } |
12 | if (substr($str, 0, 4) == 'MThd' && $extname != 'txt') |
13 | { |
14 | $format = 'mid'; |
15 | } |
16 | elseif (substr($str, 0, 4) == 'RIFF' && $extname == 'wav') |
17 | { |
18 | $format = 'wav'; |
19 | } |
20 | elseif (substr($str ,0, 3) == "/xFF/xD8/xFF") |
21 | { |
22 | $format = 'jpg'; |
23 | } |
24 | elseif (substr($str ,0, 4) == 'GIF8' && $extname != 'txt') |
25 | { |
26 | $format = 'gif'; |
27 | } |
28 | elseif (substr($str ,0, 8 ) == "/x89/x50/x4E/x47/x0D/x0A/x1A/x0A") |
29 | { |
30 | $format = 'png'; |
31 | } |
32 | elseif (substr($str ,0, 2) == 'BM' && $extname != 'txt') |
33 | { |
34 | $format = 'bmp'; |
35 | } |
36 | elseif ((substr($str ,0, 3) == 'CWS' || substr($str ,0, 3) == 'FWS') && $extname != 'txt') |
37 | { |
38 | $format = 'swf'; |
39 | } |
40 | elseif (substr($str ,0, 4) == "/xD0/xCF/x11/xE0") |
41 | { // D0CF11E == DOCFILE == Microsoft Office Document |
42 | if (substr($str,0x200,4) == "/xEC/xA5/xC1/x00" || $extname == 'doc') |
43 | { |
44 | $format = 'doc'; |
45 | } |
46 | elseif (substr($str,0x200,2) == "/x09/x08" || $extname == 'xls') |
47 | { |
48 | $format = 'xls'; |
49 | } elseif (substr($str,0x200,4) == "/xFD/xFF/xFF/xFF" || $extname == 'ppt') |
50 | { |
51 | $format = 'ppt'; |
52 | } |
53 | } elseif (substr($str ,0, 4) == "PK/x03/x04") |
54 | { |
55 | $format = 'zip'; |
56 | } elseif (substr($str ,0, 4) == 'Rar!' && $extname != 'txt') |
57 | { |
58 | $format = 'rar'; |
59 | } elseif (substr($str ,0, 4) == "/x25PDF") |
60 | { |
61 | $format = 'pdf'; |
62 | } elseif (substr($str ,0, 3) == "/x30/x82/x0A") |
63 | { |
64 | $format = 'cert'; |
65 | } elseif (substr($str ,0, 4) == 'ITSF' && $extname != 'txt') |
66 | { |
67 | $format = 'chm'; |
68 | } elseif (substr($str ,0, 4) == "/x2ERMF") |
69 | { |
70 | $format = 'rm'; |
71 | } elseif ($extname == 'sql') |
72 | { |
73 | $format = 'sql'; |
74 | } elseif ($extname == 'txt') |
75 | { |
76 | $format = 'txt'; |
77 | } |
78 | |
79 | echo $format; |
本文介绍了如何使用十六进制方式查看文件头部信息以检查文件类型,并通过PHP代码实例展示了如何解析文件头部信息来确定文件类型。文章还提供了一个类的实现,用于通过文件名获取文件类型,包括处理文件存在性、文件打开错误及文件头部信息解析。
690

被折叠的 条评论
为什么被折叠?



