You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于魔数提取iWork套件的正确MIME类型?Exiftool识别异常

正确提取iWork文件的真实MIME类型(绕过Exiftool的zip识别)

嗨,这个问题我之前也碰到过!确实,iWork的.pages/.numbers/.keynote文件本质是zip压缩包,所以Exiftool只会识别外层的zip魔数,返回application/zip,但我们可以通过读取压缩包内部的标识文件来获取真实的MIME类型。下面分两种方法给你解决:

方法一:用Python脚本验证(适配Alpine Docker环境)

Alpine的Python标准库已经包含我们需要的zipfile和plistlib模块,不需要额外安装依赖。核心思路是:iWork压缩包内部的Info.plist文件存储了官方的统一类型标识(UTI),我们可以解析这个文件并映射到对应的MIME类型。

示例代码

import zipfile
import plistlib
from typing import Optional

# 映射iWork的UTI到标准MIME类型
IWORK_UTI_TO_MIME = {
    "com.apple.iwork.pages.sffpages": "application/vnd.apple.pages",
    "com.apple.iwork.numbers.sffnumbers": "application/vnd.apple.numbers",
    "com.apple.iwork.keynote.sffkey": "application/vnd.apple.keynote",
    # 兼容旧版iWork格式(如果需要)
    "com.apple.pages": "application/vnd.apple.pages",
    "com.apple.numbers": "application/vnd.apple.numbers",
    "com.apple.keynote": "application/vnd.apple.keynote"
}

def get_iwork_mime(file_path: str) -> Optional[str]:
    # 先检查是否是zip文件(魔数验证)
    with open(file_path, 'rb') as f:
        magic_number = f.read(4)
        if magic_number != b'\x50\x4b\x03\x04':
            return None  # 不是zip格式,直接返回None
    
    # 尝试读取zip内的Info.plist
    try:
        with zipfile.ZipFile(file_path, 'r') as zf:
            # 先尝试根目录的Info.plist(新版iWork)
            if 'Info.plist' in zf.namelist():
                with zf.open('Info.plist') as plist_file:
                    plist_data = plistlib.load(plist_file)
                    uti = plist_data.get('UTTypeIdentifier')
                    return IWORK_UTI_TO_MIME.get(uti)
            # 旧版iWork可能在Metadata文件夹下
            elif 'Metadata/Info.plist' in zf.namelist():
                with zf.open('Metadata/Info.plist') as plist_file:
                    plist_data = plistlib.load(plist_file)
                    uti = plist_data.get('UTTypeIdentifier')
                    return IWORK_UTI_TO_MIME.get(uti)
            else:
                return None
    except (zipfile.BadZipFile, plistlib.InvalidFileException):
        return None

# 使用示例
if __name__ == "__main__":
    import sys
    if len(sys.argv) != 2:
        print("Usage: python3 iwork_mime.py <file_path>")
        sys.exit(1)
    mime_type = get_iwork_mime(sys.argv[1])
    if mime_type:
        print(f"真实MIME类型: {mime_type}")
    else:
        print("无法识别为iWork文件,或文件损坏")

在Alpine Docker中运行

  1. 确保你的Alpine镜像安装了python3:apk add --no-cache python3
  2. 将上述代码保存为iwork_mime.py
  3. 运行:python3 iwork_mime.py your_file.pages

方法二:命令行快速验证(无需Python)

如果你不想写脚本,也可以用Alpine自带的unzip和plutil工具直接提取UTI并映射:

# 提取UTI
UTI=$(unzip -p your_file.pages Info.plist 2>/dev/null | plutil -extract UTTypeIdentifier raw - 2>/dev/null)
# 根据UTI映射MIME类型
case $UTI in
    com.apple.iwork.pages*) echo "application/vnd.apple.pages" ;;
    com.apple.iwork.numbers*) echo "application/vnd.apple.numbers" ;;
    com.apple.iwork.keynote*) echo "application/vnd.apple.keynote" ;;
    *) echo "无法识别为iWork文件" ;;
esac

注意:如果是旧版iWork文件,可能需要把Info.plist换成Metadata/Info.plist。

为什么这个方法可行?

iWork文件本质是结构化的zip包,苹果在内部的plist文件中嵌入了官方的类型标识,这个标识直接对应标准的MIME类型,比单纯依赖魔数更准确(毕竟zip魔数太通用了)。

内容的提问来源于stack exchange,提问作者znndrd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:32:59