拆分两个串联文件

use*_*180 9 split binary cat

我已经Afile做了相当于cat a.gif b.7z > Afile.

如何拆分Afile为原始文件a.gifb.7z文件?

Sté*_*las 30

您必须弄清楚 gif 的结束位置和 7z 的开始位置。

如果您不知道 gif 文件的原始大小,您可以尝试找出文件的开头,7z该文件应以字符开头7z

如果你幸运的话:

grep -boa 7z Afile
Run Code Online (Sandbox Code Playgroud)

(假设 GNU 实现grep或兼容其非标准-bbyte 偏移),-oo仅输出匹配部分)-aa所有文件,包括非文本文件))将仅返回一个:

<offset>:7z
Run Code Online (Sandbox Code Playgroud)

其中的行将<offset>是文件中文件7z开始处的偏移量。

然后,您可以使用以下命令提取它们:

tail -c +<offset+1> Afile > b.7z
head -c <offset> Afile > a.gif
Run Code Online (Sandbox Code Playgroud)

例如,如果grep返回1234:7z,则运行tail -c +1235 Afile > b.7zhead -c 1234 > a.gif

如果grep返回多个,其中一个将是 7z 文件的开头,而其他文件将只是恰好包含 0x37 0x7a(ASCII集中的7和字符的值)字节序列的 gif 或 7z 文件。z

要确定哪个是正确的,您可以将tail -c每个的输出通过管道传输到file -哪个应该返回类似于7-zip archive data正确的输出。或者甚至尝试列出其内容,bsdtar tf -例如。

tail -c +<offset+1> Afile | file -
tail -c +<offset+1> Afile | bsdtar tf -
Run Code Online (Sandbox Code Playgroud)

binwalk实用程序可用于自动化该过程,因为它尝试在文件内查找文件格式签名(通常用于从固件映像中提取信息):

$ binwalk Afile

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             GIF image data, version "89a", 584 x 137
8570          0x217A          7-zip archive data, version 0.4
Run Code Online (Sandbox Code Playgroud)

理想情况下,正如 @Henrik 在评论中指出的那样,您需要查看 gif 部分元数据以获取有关 GIF 数据结尾位置的信息。我检查了 ImageMagick identify、GNU extract、perlImage::Infoexiftool报告图像信息的常用工具,不幸的是,它们都没有报告该信息。

通过研究GIF 图像格式规范,很可能可以手动完成此操作,另一种方法可能是连接到图像查看器或转换器,以查看它们在尝试解析文件时停止读取文件的位置。

我发现这款giftopnm古老的netpbm软件可以让我做到这一点。在 zsh 中:

zmodload zsh/system
{
  giftopnm > /dev/null
  head -c $(( systell(0) )) < Afile > a.gif
  cat > b.7z
} < Afile
Run Code Online (Sandbox Code Playgroud)

在我的测试中,giftopnm在转换为 pnm 后,将 gif 文件末尾处的位置保留在 stdin 中(我们在此将其丢弃)。

假设 gif 在数据结束后还没有额外的信息,这看起来并不罕见。例如,参见 libreoffice gallery/htmlexpo/bludown.gif,它在有用数据末尾后有 212 个看似随机的字节。其中cut.gif似乎openjdk有 949 个额外字节(几乎是文件大小的 80%!),包括一些 Sun Microsystems 版权声明(未由 清理mat2