告别瞎猜文件类型:Google 开源 Magika,用 AI 精准识别文件内容
你有没有遇到过这种情况:同事发来一个没有后缀名的文件,或者从某个老旧系统里导出一批文件,扩展名全是 .dat。你试着用文本编辑器打开,看到一堆乱码;用系统自带的 file 命令试试,结果模棱两可;只好一个个拖进不同软件里试,看哪个能打开。运气好几分钟搞定,运气不好半小时就搭进去了。
Google 开源了一个叫 Magika 的工具,就是来解决这个问题的。它用深度学习模型识别文件类型,不依赖文件名、不依赖扩展名,直接读文件内容给出判断。官方说他们在 Gmail、Google Drive 和 Safe Browsing 里已经用上了,每周处理数千亿次识别请求。
我第一时间在自己的机器上试了一下,确实有点东西。这篇文章就把它的安装、使用和实际体验拆开来说清楚。
这玩意儿到底有多准?接近 99% 的判断正确率
Magika 说白了就是一个 AI 模型,它专门用来回答一个问题:「这个文件到底是什么格式?」
和传统工具不一样的是,它不靠文件头部的“魔数”硬匹配,也不看扩展名,而是用一种更灵活的方式——深度学习。所谓深度学习,你可以理解成让模型看了海量的样本之后,自己学会了判断逻辑。官方给的数据是,训练和评估用的样本接近 1 亿个,覆盖了 200 多种文件类型。这个规模其实挺夸张的,基本上你日常能碰到的文件格式都在里面了。
测试集上的准确率能做到 99% 左右。我自己测试了十几个不太常见的格式,包括一些没有扩展名的文本文件,基本都识别对了。
技术层面的另一个特点是快。模型加载是一次性开销,加载完成后,单次识别大概 5 毫秒。5 毫秒什么概念?你眨一下眼大概需要 100 到 150 毫秒,也就是说你眨一次眼的时间,Magika 能跑完二三十次识别。而且这个速度跟文件大小几乎没关系,它只读取文件的一小部分内容做判断,所以不管是 1KB 的配置文件还是 1GB 的视频文件,识别时间差不多。
还有一个细节我觉得挺有意思:Magika 内置了一套阈值机制。如果模型对自己的判断信心不足,它不会硬猜一个具体类型,而是返回一个更宽泛的标签,比如“Generic text document”或者“Unknown binary data”。这个设计在安全场景下尤其重要——宁可承认不确定,也不要给一个错误的确定性结论。
怎么装?三种方式,三分钟搞定
安装方式有好几种,看你习惯用哪种工具链。
「第一种,如果你日常写 Python:」
pipx install magika
如果你没装 pipx,直接用 pip 也行:
pip install magika
不过 pip 装的话最好在虚拟环境里操作,避免依赖冲突。
「第二种,macOS 或 Linux 用户,用 Homebrew:」
brew install magika
这条命令会把 Magika 的命令行工具装到系统路径,装完直接在终端敲 magika 就能用。
「第三种,通用方案,用官方提供的安装脚本:」
macOS / Linux:
curl -LsSf https://securityresearch.google/magika/install.sh | sh
Windows 用 PowerShell:
powershell -ExecutionPolicy Bypass -c "irm https://securityresearch.google/magika/install.ps1 | iex"
这种方式的优势是不依赖任何语言环境,直接下载二进制文件。装完之后用 magika --version 检查一下,能看到版本号就说明搞定了。
另外如果你是 Rust 开发者,也可以用 Cargo 安装:
cargo install --locked magika-cli
命令行上手:最常用的几种玩法
装好之后,最基础的使用方式就是直接给一个文件路径:
magika myfile
输出会告诉你这个文件是什么类型。默认输出是人类可读的描述文字,但实际用起来你会发现有不少场景需要更灵活的格式。
「需要简洁标签的时候,加 -l:」
magika -l myfile
输出只有一个短标签,比如 python、jpg、pdf,适合脚本里做逻辑判断。
「需要 MIME 类型的时候,加 -i:」
magika -i myfile
做 Web 开发的时候经常需要根据文件内容动态设置 Content-Type 头,这个组合就很顺手。
「想看置信度分数,加 -s:」
magika -s myfile
分数范围 0 到 1,越接近 1 表示模型越有把握。我试下来大多数正常文件的分数都在 0.98 以上,但也有少数边缘情况在 0.7 左右徘徊。这时候你就知道“哦,模型对这个判断其实不是特别确定”。
「批量处理目录,用 -r:」
magika -r ./some_folder/
它会递归扫描目录下的所有文件,挨个输出识别结果。官方示例里跑过这样一个命令:
cd tests_data/basic && magika -r *
输出结果从 Assembly 代码、批处理文件、C 源代码,到 Word 文档、邮件文件、空文件,一次性全部识别出来,类型标签清晰明了。
「输出 JSON 格式,用 --json:」
magika --json myfile
返回的 JSON 结构包含了完整信息:路径、识别结果、置信度分数、MIME 类型、所属分组、常见扩展名列表等等。这个模式适合把 Magika 集成到自动化流水线或者后端服务里。
[
{
"path": "./tests_data/basic/python/code.py",
"result": {
"status": "ok",
"value": {
"dl": {
"description": "Python source",
"extensions": ["py", "pyi"],
"group": "code",
"is_text": true,
"label": "python",
"mime_type": "text/x-python"
},
"output": {
"description": "Python source",
"extensions": ["py", "pyi"],
"group": "code",
"is_text": true,
"label": "python",
"mime_type": "text/x-python"
},
"score": 0.996999979019165
}
}
}
]
「自定义输出格式,用 --format:」
如果你对默认输出不满意,可以自己拼装格式。占位符支持这些:
-
%p:文件路径 -
%l:类型标签 -
%d:类型描述 -
%g:类型分组 -
%m:MIME 类型 -
%e:常见扩展名 -
%s:置信度分数 -
%S:百分比显示的置信度
比如我想输出“路径 => 标签(分数)”:
magika --format "%p => %l (%s)" myfile
「从标准输入读数据:」
用短横线 - 代替文件路径,Magika 就会从标准输入读取内容:
cat myfile | magika -
或者:
echo "function log(msg) {console.log(msg);}" | magika -
这样即使文件不在磁盘上,也能做识别。
在代码里调用:Python 和 JavaScript 集成
命令行工具适合一次性任务,但如果你要在应用里集成文件识别能力,用 SDK 更合适。
「Python 集成」
安装:
pip install magika
使用起来非常直接。识别字节数据用 identify_bytes:
from magika import Magika
m = Magika()
res = m.identify_bytes(b'function log(msg) {console.log(msg);}')
print(res.output.label) # 输出: javascript
识别文件路径用 identify_path:
from magika import Magika
m = Magika()
res = m.identify_path('./tests_data/basic/ini/doc.ini')
print(res.output.label) # 输出: ini
识别已打开的文件流用 identify_stream:
from magika import Magika
m = Magika()
with open('./tests_data/basic/ini/doc.ini', 'rb') as f:
res = m.identify_stream(f)
print(res.output.label) # 输出: ini
这里有一个点值得提一下:Magika 对象的初始化会加载模型文件,这个操作有一点开销。如果是在服务端使用,建议在应用启动时初始化一次,然后复用这个实例,而不是每次请求都重新创建。
「JavaScript / TypeScript 集成」
Magika 也提供了 npm 包。官方提到这个包目前还是实验性质,但已经可以用了:
npm install magika
这个包的运行方式比较有意思——它跑在本地浏览器里,不用把文件上传到任何服务器。Google 官方还做了一个 Web Demo,你直接在浏览器里上传文件,所有计算都在本地完成,隐私方面完全放心。
谁在用这东西?Google 自己的大规模实践
Magika 不是一个实验室里的小玩具,它在 Google 内部已经跑在核心业务上了。
-
「Gmail」:邮件附件的上传流程里,Magika 负责判断附件类型,然后路由到对应的安全扫描器。不同格式的附件,安全扫描的策略是不一样的。 -
「Google Drive」:用户上传的文件同样会经过 Magika 识别,用于执行合适的内容安全策略。恶意文件伪装成正常文件的情况并不少见,文件类型识别是第一道防线。 -
「Safe Browsing」:Google 的安全浏览服务每天要处理海量样本,Magika 在这里也承担了文件类型判断的职责。
另外,安全社区的两个知名平台——VirusTotal 和 abuse.ch——也集成了 Magika。安全分析人员上传可疑文件之后,Magika 会帮忙快速判断文件类型,辅助后续分析决策。
这些场景的共同特点是:数据量巨大,对性能和准确率要求极高。Magika 能在这些地方落地,至少说明它在工程上经得起考验。
和传统 file 命令比,有什么不一样?
Linux 下有个历史悠久的 file 命令,它也做文件类型识别。那 Magika 和它有什么区别?
file 命令主要依赖两种方法。一种是“魔数匹配”——检查文件头部有没有某个固定模式的字节序列,比如 PDF 文件开头一定是 %PDF,PNG 图片开头一定是 \x89PNG。另一种是扩展名映射,看到 .txt 就认为是文本文件,看到 .jpg 就认为是 JPEG 图片。
魔数匹配这个方法本身没有错,但有两个局限。第一,覆盖面依赖于人工维护的特征库,遇到新格式或者变种可能就不认识。第二,对于文本类文件,这个方法基本失效——一段 Python 代码和一段 JavaScript 代码,文件头部没有本质区别,靠魔数根本分不出来。
Magika 的深度学习方案相当于把“识别特征”这件事交给模型自动学习,不需要人工为每个格式编写规则。尤其是对文本类文件的表现,据官方数据是明显优于传统方法的。
但这并不意味着 file 命令就被淘汰了。对于规范的二进制格式,file 足够快、足够可靠。Magika 更像是一个补充选项——当你发现 file 识别不出来,或者识别结果太笼统的时候,换 Magika 试试,大概率有惊喜。
几个容易踩的坑
「1. 模型加载开销」
这个前面提过,但值得再说一遍。Magika 对象初始化的时候会加载模型文件,几 MB 大小,加载需要一点时间。如果你是写命令行脚本那无所谓,但如果是写 Web 服务,别忘了做单例复用。
「2. 不要传整个大文件」
Magika 的设计是只读文件头部,这是它快的根本原因。实际调用的时候,它内部会自动控制读取范围,不需要你手动截断。但是,如果你想在应用里做优化,可以留意这一点——你不用先把整个 1GB 视频文件读进内存再传给 Magika,它只需要前几 KB。
「3. 置信度低的时候怎么办」
如果你看到某个文件的置信度分数只有 0.6 或 0.7,不要强行采信这个结果。这时候 Magika 自己都在摇摆不定,返回的 label 只是“相对最像的那个”。可以考虑走人工复核,或者结合其他信息综合判断。这也是为什么官方提供了不同的预测模式——high-confidence 模式下,Magika 只在分数很高时才给具体类型,否则返回通用标签;best-guess 模式则无论如何都给一个最可能的答案。两种模式没有绝对好坏,看你的业务场景对“误报”还是“漏报”更敏感。
实用摘要
-
Magika 是 Google 开源的文件类型识别工具,基于深度学习,准确率约 99%,支持 200+ 种文件类型。 -
安装方式: pipx install magika、brew install magika、或官方安装脚本。 -
基础命令: magika <文件路径>,递归扫描加-r,JSON 输出加--json。 -
Python 集成: Magika().identify_path()、identify_bytes()、identify_stream()。 -
速度:单次识别约 5ms,与文件大小无关。 -
和传统 file命令互补,文本类文件识别是它的强项。 -
注意模型加载的一次性开销,服务端应用请复用实例。
一页速览
| 场景 | 命令 / 代码 |
|---|---|
| 安装(pipx) | pipx install magika |
| 安装(brew) | brew install magika |
| 基础识别 | magika myfile |
| 递归识别目录 | magika -r ./folder/ |
| 只输出标签 | magika -l myfile |
| 输出 MIME 类型 | magika -i myfile |
| 显示置信度分数 | magika -s myfile |
| JSON 格式输出 | magika --json myfile |
| 自定义输出格式 | magika --format "%p: %l (%s)" myfile |
| 从 stdin 读取 | cat myfile | magika - |
| Python 识别字节 | Magika().identify_bytes(data) |
| Python 识别路径 | Magika().identify_path(path) |
| Python 识别流 | Magika().identify_stream(file_obj) |
常见问题
「Magika 会把我的文件内容上传到服务器吗?」
不会。模型在本地加载,所有计算都在本地完成,不需要联网,也不会上传任何数据。
「支持 Windows 吗?」
支持。Windows、macOS、Linux 都有对应的安装方式。
「能识别哪些文件类型?」
目前覆盖 200 多种内容类型,包括常见二进制格式(图片、音视频、压缩包、可执行程序)和大量文本格式(源代码、配置文件、文档、邮件等)。具体列表可以参考官方文档里的模型说明。
「和系统自带的 file 命令有什么区别?」
file 命令依赖魔数匹配和扩展名,识别文本类文件比较弱。Magika 用深度学习,对文本类文件的识别更准,覆盖面也更广。两者互补使用效果最好。
「这个项目是 Google 官方支持的吗?」
官方声明里说这不是一个正式 Google 项目,不享受 Google 的产品支持。不过它确实在 Google 内部大规模使用,代码质量是有保障的。
「商用的话需要注意什么?」
Magika 采用 Apache 2.0 许可证,商用友好。具体条款可以看项目仓库里的 LICENSE 文件。

