核心代码:

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # @Author : suk
  4. import struct
  5. from io import BytesIO
  6.  
  7. # 支持文件类型
  8. # 用16进制字符串的目的是可以知道文件头是多少字节
  9. # 各种文件头的长度不一样,少则2字符,长则8字符
  10. def typeList(types):
  11. type_dict = {'jpg': ['FFD8FFE000104A464946'],
  12. 'png': ['89504E470D0A1A0A0000'],
  13. 'gif': ['47494638396126026F01'],
  14. 'tif': ['49492A00227105008037'],
  15. 'bmp': ['424D8E1B030000000000'],
  16. 'dwg': [''],
  17. 'html': ['3C21444F435459504520'],
  18. 'htm': ['3C21646F637479706520'],
  19. 'css': ['48544D4C207B0D0A0942'],
  20. 'js': ['696B2E71623D696B2E71'],
  21. 'rtf': ['7B5C727466315C616E73'],
  22. 'psd': [''],
  23. 'eml': ['46726F6D3A203D3F6762'],
  24. 'wps': ['D0CF11E0A1B11AE10000'],
  25. 'mdb': ['5374616E64617264204A'],
  26. 'ps': '[252150532D41646F6265]',
  27. 'pdf': ['255044462D312E'],
  28. 'rmvb': ['2E524D46000000120001'],
  29. 'flv': ['464C5601050000000900'],
  30. 'mp4': ['00000020667479706D70'],
  31. 'mp3': [''],
  32. 'mpg': ['000001BA210001000180'],
  33. 'wmv': ['3026B2758E66CF11A6D9'],
  34. 'wav': ['52494646E27807005741'],
  35. 'avi': ['52494646D07D60074156'],
  36. 'mid': ['4D546864000000060001'],
  37. 'zip': ['504B0304140000000800', '504B0304140000080800', '504B03040A0000080000'],
  38. 'rar': ['526172211A0700CF9073'],
  39. 'ini': ['235468697320636F6E66'],
  40. 'jar': ['504B03040A0000000000'],
  41. 'exe': ['4D5A9000030000000400'],
  42. 'jsp': ['3C25402070616765206C'],
  43. 'mf': ['4D616E69666573742D56'],
  44. 'xml': ['3C3F786D6C2076657273'],
  45. 'sql': ['494E5345525420494E54'],
  46. 'java': ['7061636B616765207765'],
  47. 'bat': ['406563686F206F66660D'],
  48. 'gz': ['1F8B0800000000000000'],
  49. 'properties': ['6C6F67346A2E726F6F74'],
  50. 'class': ['CAFEBABE0000002E0041'],
  51. 'chm': [''],
  52. 'mxp': [''],
  53. 'docx': ['504B0304140006000800', '504B03040A0000000000'],
  54. 'torrent': ['6431303A637265617465'],
  55. 'mov': ['6D6F6F76'],
  56. 'wpd': ['FF575043'],
  57. 'dbx': ['CFAD12FEC5FD746F'],
  58. 'pst': ['2142444E'],
  59. 'qdf': ['AC9EBD8F'],
  60. 'pwl': ['E3828596'],
  61. 'ram': ['2E7261FD']
  62. }
  63. ret = {}
  64. for k_hex, v_prefix in type_dict.items():
  65. if k_hex in types:
  66. ret[k_hex] = v_prefix
  67. return ret
  68.  
  69. # 字节码转16进制字符串
  70. def bytes2hex(bytes):
  71. num = len(bytes)
  72. hexstr = u""
  73. for i in range(num):
  74. t = u"%x" % bytes[i]
  75. if len(t) % 2:
  76. hexstr += u""
  77. hexstr += t
  78. return hexstr.upper()
  79.  
  80. # 获取文件类型
  81. def file_type(filename):
  82. binfile = open(filename, 'rb') # 必需二制字读取
  83. tl = typeList(types=["jpg", "zip", "docx"])
  84. ftype = None
  85. for type_name, hcode_list in tl.items():
  86. flag = False
  87. for hcode in hcode_list:
  88. numOfBytes = int(len(hcode) / 2) # 需要读多少字节
  89. binfile.seek(0) # 每次读取都要回到文件头,不然会一直往后读取
  90. hbytes = struct.unpack_from("B" * numOfBytes, binfile.read(numOfBytes)) # 一个 "B"表示一个字节
  91. f_hcode = bytes2hex(hbytes) # 如果判断不出来,打印出这个值,往字典增加即可
  92. # print("上传数据流hex", s_hcode, '=', "代码字典hex", hcode) # 如果判断不出来,打印出这个值,往字典增加即可
  93. if f_hcode == hcode:
  94. flag = True
  95. break
  96. if flag:
  97. ftype = type_name
  98. break
  99. binfile.close()
  100. return ftype
  101.  
  102. # 获取字节流类型
  103. def stream_type(stream, types):
  104. """
  105. :param stream:流数据
  106. :param types:需要判断文件类型,格式:["jpg","jpn"]
  107. :return:
  108. """
  109. tl = typeList(types=types)
  110. ftype = None
  111. for type_name, hcode_list in tl.items():
  112. flag = False
  113. for hcode in hcode_list:
  114. numOfBytes = int(len(hcode) / 2) # 需要读多少字节
  115. hbytes = struct.unpack_from("B" * numOfBytes, stream[0:numOfBytes]) # 一个 "B"表示一个字节
  116. s_hcode = bytes2hex(hbytes)
  117. # print("上传数据流hex", s_hcode, '=', "代码字典hex", hcode) # 如果判断不出来,打印出这个值,往字典增加即可
  118. if s_hcode == hcode:
  119. flag = True
  120. break
  121. if flag:
  122. ftype = type_name
  123. break
  124. return ftype
  125.  
  126. def stream_split(stream, count=3):
  127. """
  128. 主要处理流是分段获取的数据
  129. :param stream: 块流
  130. :param count: 取多少段合成来判断类型,默认三段
  131. :return:
  132. """
  133. block_stream = BytesIO()
  134. temp = 1
  135. for block in stream:
  136. block_stream.write(block)
  137. if temp == count:
  138. break
  139. temp += 1
  140. return block_stream.getvalue()

is_file_type.py

  1. type_dict字典,根据自己上传的文件,来填写,数据来自互联网。

基于Flask的上传示例

  1. @index.route('/upload', methods=['GET', 'POST'])
  2. def upload():
  3.  
  4. if request.method == 'GET':
  5. return render_template('upload.html')
  6.  
  7. upload_obj = request.files.get('code_file')
  8.  
  9. if not upload_obj:
  10. return '没有选择文件上传'
  11.  
  12. ret = stream_type(stream_split(upload_obj.stream), ["jpg", "png", "pdf"])
  13.  
  14. if not ret:
  15. return '上传失败,文件类型不匹配,类型必须 "jpg" or "png" or "pdf"'
  16.  
  17. file_name = upload_obj.filename
  18. upload_obj.save(os.path.join('files', file_name))
  19.  
  20. return '上传文件成功'

upload.html

  1. {% extends 'layout.html' %}
  2. {% block content %}
  3. <h1>上传代码</h1>
  4. <form action="" method="post" enctype="multipart/form-data">
  5. <input type="file" name="code_file">
  6. <input type="submit" value="上传"></input>
  7. </form>
  8. {% endblock %}

开始上传文件:

上传不在列表中的文件类型


上传在列表中的文件类型

Python之基于十六进制判断文件类型的更多相关文章

  1. Python使用filetype精确判断文件类型

    Python使用filetype精确判断文件类型 判断文件类型在开发中非常常见的需求,怎样才能准确的判断文件类型呢?首先大家想到的是文件的后缀,但是非常遗憾的是这种方法是非常不靠谱的,因为文件的后缀是 ...

  2. 【转】python通过文件头判断文件类型

    刚刚看到一个好玩的程序,拉过来.原文地址:https://www.ttlsa.com/python/determine-file-type-by-the-file-header/ 侵权删. ===== ...

  3. Python使用filetype精确判断文件类型 (文件类型获取)

    filetype.py Small and dependency free Python package to infer file type and MIME type checking the m ...

  4. python准确判断文件类型

    判断文件类型在开发中非常常见的需求,怎样才能准确的判断文件类型呢?首先大家想到的是文件的后缀,但是非常遗憾的是这种方法是非常不靠谱的,因为文件的后缀是可以随意更改的,而大家都知道后缀在linux系统下 ...

  5. JavaScript根据文件名判断文件类型

    //JavaScript根据文件名判断文件类型 var imgExt = new Array(".png",".jpg",".jpeg",& ...

  6. 利用PHP取二进制文件头判断文件类型

    <?php $files = array('D:\no.jpg', 'D:\no.png','D:\no2.JPEG','D:\no.BMP'); $fileTypes = array( 779 ...

  7. Linux中用st_mode判断文件类型

    Linux中用st_mode判断文件类型 2012-12-11 12:41 14214人阅读 评论(4) 收藏 举报  分类: Linux(8)  C/C++(20)  版权声明:本文为博主原创文章, ...

  8. php 读取文件头判断文件类型的实现代码

    php代码实现读取文件头判断文件类型,支持图片.rar.exe等后缀. 例子: <?php $filename = "11.jpg"; //为图片的路径可以用d:/uploa ...

  9. PHP取二进制文件头快速判断文件类型的实现代码

    通过读取文件头信息来识别文件的真实类型. 一般我们都是按照文件扩展名来判断文件类型,但是这个很不靠谱,轻易就通过修改扩展名来躲避了,一般必须要读取文件信息来识别,PHP扩展中提供了类似 exif_im ...

随机推荐

  1. AKKA文档2.3(java版)—什么是角色

    原文:http://doc.akka.io/docs/akka/2.3.5/general/actors.html译者:Vitas 什么是角色? 前面角色系统一节介绍了一群角色如何形成一个层次结构,并 ...

  2. 用IDEA开发Spring程序

    操作步骤 https://www.cnblogs.com/zyx110/p/11023218.html

  3. Shell初学(八)linux下的ACL

    [1]ACL的作用 简单直接解释一下ACL的作用,即把权限的个别化额外添加. 可以解决如下问题~~比如: [1.1]基于用户: 我有10个用户a1-a10,我有一个文件夹/tmp/test,我想给a1 ...

  4. mysql事件(event)

    [小结]简单案例 SET GLOBAL event_scheduler=1delimiter $$ create definer = current_user event `test`.`event_ ...

  5. HanLP-分类模块的分词器介绍

    最近发现一个很勤快的大神在分享他的一些实操经验,看了一些他自己关于hanlp方面的文章,写的挺好的!转载过来分享给大家!以下为分享原文(无意义的内容已经做了删除) 如下图所示,HanLP的分类模块中单 ...

  6. p1000 A+B问题

    题目描述 Description 输入两个整数A和B,输出他们的和 输入描述 Input Description 输入为一行,包含两个整数A,B.数据保证A与B都在2^31-1的范围内 输出描述 Ou ...

  7. flower 时区设置

    celery 搭配flower使用,flower默认使用的是UTC时间,那么如何在flower中使用当前城市的时间呢 我的环境 celery 3.1.25 ,python 3.69 1.在 app设置 ...

  8. 什么是云数据库RDS PPAS 版

    云数据库PPAS版,是阿里云与EnterpriseDB公司合作基于PostgreSQL高度兼容Oracle语法的数据库服务,为用户提供易于操作的迁移工具,兼容范围涵盖:PL/SQL.数据类型.高级函数 ...

  9. 初入JavaWeb(半成品)

    2019-10-21 20:51:03 初次进行Javaweb的开发. 要求: 1登录账号:要求由6到12位字母.数字.下划线组成,只有字母可以开头:(1分) 2登录密码:要求显示“• ”或“*”表示 ...

  10. Unity VR-播放demo模型后无法移动视角

    资源源于:小意思VR 唉..可怜一下自己,这个问题百度google也不知道怎么搜,没搜出来,在群里问出来的. 当时感觉自己Unity有问题..(就是因为自己啥也不会看不懂) 按右键.或者WASD视角都 ...