Go语言 通过文件流判断文件头来识别文件类型
系统中需要用到文件上传的功能,但是从系统安全的角度上来说需要判断上传文件的格式,防止将病毒木马等有害的文件上传到服务器上。
判断文件类型有三种方式
1、通过文件后缀名
这个方法简单容易,但是也是最容易被欺骗的方法,修改文件的后缀名即可实现欺骗系统。
2、通过Content-Type判断
这个是通过判断文件的MIME类型进行判断,我们在通过form表单上传文件时,在上传的request域里面会获取当前文件的MIME类型,我们可以通过控制接收文件的MIME类型进行判断。这个方法如果通过抓包的形式进行修改类型也不安全。
安全问题详解:
https://www.cnblogs.com/dunitian/p/5645339.html
注意:现在遇见一个问题就是在angular框架下通过consumes参数进行控制上传文件类型时,当错误类型时会产生415(不被允许的多媒体类型),但是正确类型时,会产生ERROR_CONNECTION_RESET连接重定向错误。(待解决)
3、通过文件流判断文件头
package utilsimport ("bytes""encoding/hex""strconv""strings""sync"
)var fileTypeMap sync.Mapfunc init() {fileTypeMap.Store("ffd8ffe000104a464946", "jpg") //JPEG (jpg)fileTypeMap.Store("89504e470d0a1a0a0000", "png") //PNG (png)fileTypeMap.Store("47494638396126026f01", "gif") //GIF (gif)fileTypeMap.Store("49492a00227105008037", "tif") //TIFF (tif)fileTypeMap.Store("424d228c010000000000", "bmp") //16色位图(bmp)fileTypeMap.Store("424d8240090000000000", "bmp") //24位位图(bmp)fileTypeMap.Store("424d8e1b030000000000", "bmp") //256色位图(bmp)fileTypeMap.Store("41433130313500000000", "dwg") //CAD (dwg)fileTypeMap.Store("3c21444f435459504520", "html") //HTML (html) 3c68746d6c3e0 3c68746d6c3e0fileTypeMap.Store("3c68746d6c3e0", "html") //HTML (html) 3c68746d6c3e0 3c68746d6c3e0fileTypeMap.Store("3c21646f637479706520", "htm") //HTM (htm)fileTypeMap.Store("48544d4c207b0d0a0942", "css") //cssfileTypeMap.Store("696b2e71623d696b2e71", "js") //jsfileTypeMap.Store("7b5c727466315c616e73", "rtf") //Rich Text Format (rtf)fileTypeMap.Store("38425053000100000000", "psd") //Photoshop (psd)fileTypeMap.Store("46726f6d3a203d3f6762", "eml") //Email [Outlook Express 6] (eml)fileTypeMap.Store("d0cf11e0a1b11ae10000", "doc") //MS Excel 注意:word、msi 和 excel的文件头一样fileTypeMap.Store("d0cf11e0a1b11ae10000", "vsd") //Visio 绘图fileTypeMap.Store("5374616E64617264204A", "mdb") //MS Access (mdb)fileTypeMap.Store("252150532D41646F6265", "ps")fileTypeMap.Store("255044462d312e350d0a", "pdf") //Adobe Acrobat (pdf)fileTypeMap.Store("2e524d46000000120001", "rmvb") //rmvb/rm相同fileTypeMap.Store("464c5601050000000900", "flv") //flv与f4v相同fileTypeMap.Store("00000020667479706d70", "mp4")fileTypeMap.Store("49443303000000002176", "mp3")fileTypeMap.Store("000001ba210001000180", "mpg") //fileTypeMap.Store("3026b2758e66cf11a6d9", "wmv") //wmv与asf相同fileTypeMap.Store("52494646e27807005741", "wav") //Wave (wav)fileTypeMap.Store("52494646d07d60074156", "avi")fileTypeMap.Store("4d546864000000060001", "mid") //MIDI (mid)fileTypeMap.Store("504b0304140000000800", "zip")fileTypeMap.Store("526172211a0700cf9073", "rar")fileTypeMap.Store("235468697320636f6e66", "ini")fileTypeMap.Store("504b03040a0000000000", "jar")fileTypeMap.Store("4d5a9000030000000400", "exe") //可执行文件fileTypeMap.Store("3c25402070616765206c", "jsp") //jsp文件fileTypeMap.Store("4d616e69666573742d56", "mf") //MF文件fileTypeMap.Store("3c3f786d6c2076657273", "xml") //xml文件fileTypeMap.Store("494e5345525420494e54", "sql") //xml文件fileTypeMap.Store("7061636b616765207765", "java") //java文件fileTypeMap.Store("406563686f206f66660d", "bat") //bat文件fileTypeMap.Store("1f8b0800000000000000", "gz") //gz文件fileTypeMap.Store("6c6f67346a2e726f6f74", "properties") //bat文件fileTypeMap.Store("cafebabe0000002e0041", "class") //bat文件fileTypeMap.Store("49545346030000006000", "chm") //bat文件fileTypeMap.Store("04000000010000001300", "mxp") //bat文件fileTypeMap.Store("504b0304140006000800", "docx") //docx文件fileTypeMap.Store("d0cf11e0a1b11ae10000", "wps") //WPS文字wps、表格et、演示dps都是一样的fileTypeMap.Store("6431303a637265617465", "torrent")fileTypeMap.Store("6D6F6F76", "mov") //Quicktime (mov)fileTypeMap.Store("FF575043", "wpd") //WordPerfect (wpd)fileTypeMap.Store("CFAD12FEC5FD746F", "dbx") //Outlook Express (dbx)fileTypeMap.Store("2142444E", "pst") //Outlook (pst)fileTypeMap.Store("AC9EBD8F", "qdf") //Quicken (qdf)fileTypeMap.Store("E3828596", "pwl") //Windows Password (pwl)fileTypeMap.Store("2E7261FD", "ram") //Real Audio (ram)
}// 获取前面结果字节的二进制
func bytesToHexString(src []byte) string {res := bytes.Buffer{}if src == nil || len(src) <= 0 {return ""}temp := make([]byte, 0)for _, v := range src {sub := v & 0xFFhv := hex.EncodeToString(append(temp, sub))if len(hv) < 2 {res.WriteString(strconv.FormatInt(int64(0), 10))}res.WriteString(hv)}return res.String()
}// 用文件前面几个字节来判断
// fSrc: 文件字节流(就用前面几个字节)
func GetFileType(fSrc []byte) string {var fileType stringfileCode := bytesToHexString(fSrc)fileTypeMap.Range(func(key, value interface{}) bool {k := key.(string)v := value.(string)if strings.HasPrefix(fileCode, strings.ToLower(k)) ||strings.HasPrefix(k, strings.ToLower(fileCode)) {fileType = vreturn false}return true})return fileType
}
测试:
func TestGetFileType(t *testing.T) {//f, err := os.Open("C:\\Users\\Administrator\\Desktop\\api.html")f, err := os.Open("C:\\Users\\Administrator\\Desktop\\Wildlife.wmv")if err != nil {t.Logf("open error: %v", err)}fSrc, err := ioutil.ReadAll(f)t.Log(GetFileType(fSrc[:10]))
}
结果:
D:\GoWorks\src\server\web\backend\src\utils>go test -v
=== RUN TestGetFileType
--- PASS: TestGetFileType (0.00s)regexp_test.go:39: html
PASS
ok server/web/backend/src/utils 0.547sD:\GoWorks\src\server\web\backend\src\utils>go test -v
=== RUN TestGetFileType
--- PASS: TestGetFileType (0.07s)regexp_test.go:40: wmv
PASS
ok server/web/backend/src/utils 0.480s
转载于:https://www.cnblogs.com/enjong/articles/10741244.html
Go语言 通过文件流判断文件头来识别文件类型相关推荐
- 16进制文件头笔记及文件类型判断代码
之前做过一个功能,说是上传文件到服务器,但是所有文件excel.word.音乐.视频等都上传到一个文件夹,不利于查找,于是自己上网查询关于这方面的资料,决定按文件后缀名,给文件进行分类,存放不同的文件 ...
- java判断文件头_java通过文件头来判断文件类型
importjava.io.FileInputStream;importjava.io.IOException;importjava.util.HashMap;importjava.util.Map. ...
- Java:通过读取文件头来得到文件真实类型
誊抄自原来的笔记 背景 有时我们需要对上传的文件进行判断文件类型,一般我们可以通过扩展名来判断文件属于什么类型,但是当文件没有扩展名或者一张图片改成了txt,我们通过扩展名的方式来判断是不是就不太合适 ...
- java 文件头_常用文件的文件头(附JAVA测试类)
1. MIDI (mid),文件头:4D546864 2. JPEG (jpg),文件头:FFD8FF 3. PNG (png),文件头:89504E47 4. GIF (gif),文件头:47494 ...
- 根据文件头信息来判断文件类型
常用的判断文件类型的方法 有 根据文件类型,文件后缀,这里有一种方法,根据文件头信息来判断文件类型. 我把多余的getAllFileType() 给注释掉了,可以根据使用来选择. 这个参考了,忘了地 ...
- html的文件头标志,各类文件的文件头标志.docx
各类文件的文件头标志.docx 还剩 12页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环保! 内容要点: 扩展名 文件头标识( ...
- Oracle数据文件scn不一致,控制文件与数据文件头SCN不一致导致数据库无法启动故障处理...
环境说明 OS操作系统:WINDOWS 2012 64位 数据库版 本:ORACLE 11.2.0.1 故障问题描述 客户反映数据库无法启动,报ORA-01589:要打开数据库必须使用RESETLOG ...
- 批量给项目的java文件添加licence文件头
批量给项目的java文件添加licence文件头 package com.cs.test.springboot;import java.io.File; import java.io.FileWrit ...
- C++文件流:myfstream,fstream,文件读写,随机文件读写【C++文件流】(59)
文件流 myfstream fstream Test myfstream fstream 流对象的定义 流对象关联文件 open 函数 打开方式 关闭流对象 文件读写 读写文本文件 读写接口 读一字/ ...
- java文件流下载excel_React获取Java后台文件流下载Excel文件
记录使用blob对象接收java后台文件流并下载为xlsx格式的详细过程,关键部分代码如下. 首先在java后台中设置response中的参数: public void exportExcel(Htt ...
最新文章
- Nat. Biotechnol.扩增子测序革命—用16S及18S rRNA全长进行微生物多样性研究
- 什么是时间导数(Time derivative)
- 不是程序员也能看懂的ZCash零知识证明
- [目标检测] Faster R-CNN 深入理解 改进方法汇总
- C++ 不懂的地方 记录01
- jQuery 表格响应式插件 FooTable
- java 蓝桥杯算法训练 求完数(题解)
- nginx documentation | Development guide
- oracle update并行,Oracle update 优化方式,tuning update!
- 华北计算机系统工程研究所录取名单,2018年华北计算机系统工程研究所接收推免研究生复试录取通知...
- 【MYSQL笔记】使用存储过程
- php7 fastdfs,关于centos7 fastdfs部署
- php ddos 防御,PHP DDos的几个防御方法详解
- 一张图了解CAS单点登录的流程
- Sobel边缘检测算子OpenCV实现
- VScode 历史版本
- 【181023】VC++开发的电路板画图设计软件源代码
- java火星坐标转百度坐标_各种地理坐标系的转换,火星坐标,百度坐标,wsg84等...
- ARP协议格式和实例分析
- 2012蓝桥杯省赛真题 鲁卡斯序列