文件打不开先看 Hex:截断、CRLF 污染、下载成错误页、加密——四种「损坏」的字节特征

· 约 5 分钟 🔬 Hex 二进制查看

下载了一个几十 MB 的压缩包,双击解压,报「文件已损坏或格式未知」。或者一张图片显示不出来,看图软件只说「无法打开」。

报错信息几乎从不告诉你哪里坏了。 但把文件拖进 Hex 二进制查看,几十秒就能分辨出是哪一类问题——而这决定了你接下来该重新下载、该换传输方式,还是该去找密码。

(本文只讲排查损坏。「这是个什么格式的文件」属于另一个问题,见 文件魔数速查。)

形态一:你下到的根本不是那个文件

这是最常见的一类,而且完全不是「损坏」。

看前几个字节的 ASCII 列:

开头字节ASCII说明
3C 21 44 4F 43<!DOCHTML 页面
3C 68 74 6D 6C<htmlHTML 页面
7B 22{"JSON 错误响应

服务端返回的不是文件,而是一个页面:登录页、防盗链拦截页、CDN 的 502 错误页、过期的网盘分享页。浏览器或下载工具照单全收,存成了 .zip

更快的判据是文件大小:预期几十 MB,实际只有 3 KB——不用打开就知道了。

对策是回去看下载链接(要不要登录、Referer 对不对、链接过没过期),修文件是白费力气

形态二:头部正常,尾部缺失——传输被截断

很多格式的关键结构在文件末尾,这就是「只看魔数不够」的原因。

格式尾部标记含义
ZIP50 4B 05 06中央目录结束记录(EOCD)
PNG49 45 4E 44 AE 42 60 82IEND 块 + 固定 CRC
JPEGFF D9EOI 结束标记
PDF25 25 45 4F 46%%EOF
GZIP最后 8 字节CRC32 + 原始长度

以 ZIP 为例:EOCD 记录着包里有哪些文件、各自在什么偏移,而它在文件最末尾(无注释时是最后 22 字节)。截断丢掉尾部,解压程序就不知道包里有什么,于是报「不是有效的压缩文件」——尽管开头的 50 4B 03 04 好好的

头对尾不对 = 截断。 常见成因:下载中断后续传出错、磁盘写满、进程被杀、网盘限速超时。

这类损坏本地修不了,缺的字节就是没有了,只能重新下载。

形态三:换行字节被改写——文本模式污染

这一类最有迷惑性,因为魔数往往仍然正确,文件看着完整。

成因都是「把二进制当文本处理」:

  • FTP 的 ASCII 模式——Windows 侧把每个 0A 展开成 0D 0A,Unix 侧反向折叠
  • Git 的 autocrlf 处理了本该按二进制对待的文件,通常是 .gitattributes 没标 binary
  • 脚本用文本模式打开文件(没带 b 标志)读写

对文本无害,对 exe、zip、png、字体是致命的

hex 里的三个特征

  1. 文件比原始大小大一点点,多出的字节数正好等于原文件里 0A 的个数
  2. 0D 0A 出现得异常密集,且出现在图像数据、压缩数据这类不该有换行的区域
  3. 魔数仍然正确——所以特别容易被误判成别的问题

对策是用二进制模式重传。 已被改写的文件无法可靠还原:原文件里本来就有的 0D 0A 和转换出来的混在一起,分不清哪些该折回去。

形态四:通篇乱码——多半没坏,是加密或压缩

一片看不出规律的字节,第一反应往往是「彻底坏了」。恰恰相反。

损坏的文件加密 / 压缩的数据
局部结构还能看到可读字符串、成片的 00看不到任何重复模式
字节分布不均匀接近均匀,高熵
连续 00常见几乎没有
头部可能已经被破坏通常有容器魔数

高熵本身就是「数据完好」的证据——加密和压缩的目标就是把冗余榨干,结果必然是均匀分布。真正损坏的文件反而会露出结构的残骸。

所以看到通篇乱码,回头看头部:有 GZIP 的 1F 8B、有 ZIP 的 50 4B 03 04、有加密容器自己的固定头,就说明文件是好的,你缺的是密码或对应的工具

加密 ZIP 和损坏 ZIP 的一句话判据:标准 ZIP 加密只加密内容不加密文件名,所以能在 hex 里直接看到文件名就说明结构还在,问题在密码上;连 EOCD 都找不到,才是真的缺数据。

附:BOM 挡在魔数前面

EF BB BF 是 UTF-8 的 BOM。它出现在文件开头时,会把真正的内容整体往后挤 3 个字节

后果是解析器读到的第一个字符不是预期的 {<,于是报「格式不对」「意外的字符」——而你用编辑器打开看,一切正常,因为编辑器把 BOM 藏起来了。

只有 hex 视图能看见它。 这也是 JSON 解析、XML 解析、shell 脚本 shebang 失效这几类问题的经典成因。

按症状定位

症状hex 特征结论怎么办
体积远小于预期头部是 <!DOC / {"下到了错误页检查链接和登录态
头对尾不对尾部标记缺失传输截断重新下载
体积略大数据区 0D 0A 密集文本模式污染二进制模式重传
通篇乱码高熵、头部有魔数没坏,加密或压缩找密码 / 换工具
解析报意外字符开头 EF BB BFBOM 干扰去掉 BOM 另存

相关

总结

  • 先看文件大小,差一个数量级基本就是下到了错误页,比看 hex 还快
  • 头部只回答「是什么」,尾部才回答「全不全」,ZIP 的 EOCD、PNG 的 IEND 都在末尾
  • 截断本地修不了,缺的字节就是没有了,唯一出路是重新获取
  • 魔数正确不等于文件没问题,文本模式污染改的是中间的换行字节
  • CRLF 污染不可逆,因为分不清哪些 0D 0A 是原有的,必须二进制重传
  • 通篇高熵说明数据完好,那是加密或压缩的正常样子,不是损坏
  • EF BB BF 开头的 BOM 只有 hex 能看见,是一大类「格式不对」报错的真凶

❓ 常见问题

下载下来的文件打不开,第一步看哪里?

看前 16 个字节,能一眼排掉最常见的一类问题。把文件拖进 Hex 二进制查看,看开头这几个字节的 ASCII 列:(1) 出现 <!DOC(3C 21 44 4F 43)或 <html(3C 68 74 6D 6C) → 你下到的根本不是文件,是一个 HTML 页面——登录页、防盗链拦截页、CDN 的 502 错误页或者过期的分享页;(2) 出现 {"(7B 22) → 服务端返回的是 JSON 错误响应;(3) 出现 EF BB BF → 前面挂了个 UTF-8 BOM,把真正的魔数挤到了第 4 字节,很多解析器因此报「格式不对」;(4) 魔数正常 → 头部没问题,接着去看文件末尾辅助判据:这类「下成错误页」的文件通常只有几 KB,和预期大小差着数量级,看一眼文件大小往往比看 hex 还快。

文件头是对的,还是解压失败,接下来查什么?

查文件末尾,八成是传输被截断了。很多格式的关键结构在尾部而不是头部,头对尾不对是截断的典型特征:(1) ZIP 的中央目录结束记录 EOCD 签名是 50 4B 05 06,正常应当出现在文件最后 22 字节附近(有注释时再往前一点)——找不到它,解压程序就不知道包里有哪些文件,于是报「不是有效的压缩文件」;(2) PNG 必须以 49 45 4E 44 AE 42 60 82(IEND 块加固定 CRC)结束;(3) JPEG 必须以 FF D9 结束;(4) PDF 末尾应有 25 25 45 4F 46%%EOF)。尾部缺失的常见原因:下载中断后续传出错、磁盘写满、进程被杀、网盘限速超时。这也是为什么排查不能只看开头——魔数速查解决的是「这是什么文件」,尾部标记解决的是「这个文件全不全」。

文件明明完整,但就是用不了,还有什么可能?

很可能是被文本模式传输污染了,二进制里的换行字节被改写。(1) FTP 的 ASCII 模式会在传输时做换行转换,Windows 侧把每个 0A 展开成 0D 0A,Unix 侧反向折叠——对文本无害,对 exe、zip、png、字体这类二进制是致命的;(2) Git 的 autocrlf 处理了本该按二进制对待的文件,也会造成同样后果,通常是 .gitattributes 没把该格式标为 binary;(3) 用文本模式(没有 b 标志)打开文件读写的脚本同理。hex 里的特征:(1) 文件比原始大小大一点点,多出来的字节数正好等于原文件里 0A 的个数;(2) 0D 0A 出现得异常密集,且出现在图像数据、压缩数据这类不该有换行的区域里;(3) 魔数往往仍然正确,所以特别有迷惑性。对策是重传,用二进制模式——已经被改写的文件无法可靠还原,因为分不清哪些 0D 0A 是原有的。

打开是一片看不出规律的乱码,是文件坏了吗?

不一定,均匀的乱码恰恰说明文件是好的——它只是被加密或压缩了怎么区分:(1) 损坏的文件通常局部还能看出结构——有可读的字符串片段、有成片的 00、有重复出现的模式;(2) 加密或压缩后的数据是高熵的,字节分布接近均匀,看不到任何重复模式,也几乎没有连续的 00,从头到尾一个样。(3) 再看头部:加密容器一般有自己的魔数或固定头(很多格式会留一段明文头部记录算法和参数),而压缩包的头部有明确魔数,比如 GZIP 的 1F 8B结论:整体高熵 + 头部有可识别的容器标记 → 文件没坏,你只是需要正确的密码或解压工具;整体高熵 + 头部也是随机的 → 才需要怀疑是不是拿错了文件或者被整体覆盖。

为什么加密的 ZIP 和损坏的 ZIP 表现很像?

因为两者都让解压程序读不出内容,但在 hex 里区别很清楚。(1) 加密的 ZIP 结构完整——头部有 50 4B 03 04,尾部有 50 4B 05 06文件名甚至能在 hex 里直接看到(标准 ZIP 加密只加密内容不加密文件名),只是每个文件的数据段是高熵的;(2) 损坏的 ZIP 则是结构本身出了问题,最常见的就是尾部的 EOCD 整个不见了一句话判据能在 hex 里看到文件名,结构就还在,问题在密码或工具上;连 EOCD 都找不到,那是真的缺了数据。 顺带一提,如果文件名也看不见,那可能是用了加密文件名的方案(比如 7z 的头部加密),这仍然属于「结构完整、需要密码」那一类。

🔬 打开 Hex 二进制查看 拖入任意文件→十六进制+ASCII 三栏视图·魔数识别·PNG/JPEG/GIF/PDF/ZIP/GZIP 结构解析·点击 chunk 高亮·本地不上传

📖 同一工具的其他教程

🔗 相关阅读

全部教程 →