使用xxd修改文件魔术字节为JPEG格式时出现识别异常的问题求助
问题根源:误修改了xxd输出的文本预览区域(而非十六进制字节编码区域)
你遇到的问题核心是在xxd编辑模式下,错误地修改了右侧的ASCII文本预览区,而非左侧的十六进制字节编码区,再加上vi默认以UTF-8编码处理文本,导致输入的字符被转换成了UTF-8字节,而非你期望的原始十六进制字节值。
具体原因分析:
当执行:%!xxd后,vi会把文件内容转换成如下格式的文本:
00000000: 6162 630a abc.
- 左侧
00000000:是字节地址,后面的6162 630a是文件实际存储的字节十六进制编码——这才是需要修改的部分 - 右侧的
abc.只是这些字节对应的ASCII字符预览,修改这里只会改变预览文本,不会影响实际存储的字节
你想要写入FF D8 FF E0这些字节,但如果误在右侧文本区输入了对应的UTF-8字符(比如ÿ的UTF-8编码是C3 BF,Ø的UTF-8编码是C3 98),执行:%!xxd -r时,xxd会把右侧的文本字符转换成它们的UTF-8编码字节,最终就得到了你看到的c3bf c398 c3bf c3a0。
正确的操作步骤:
- 打开文件后执行
:%!xxd进入十六进制编辑模式 - 仅修改左侧的十六进制字节部分:找到开头的字节区域,把原有内容改成
ffd8 ffe0 0a(空格分隔不影响xxd解析,保持每两个字符对应一个字节的格式即可)
正确的编辑内容应该类似:00000000: ffd8 ffe0 0a .... - 执行
:%!xxd -r还原为二进制文件格式 - 保存退出(
:wq)
验证操作:
执行xxd test会看到预期的十六进制内容:
00000000: ffd8 ffe0 0a ....
再用file test检查,会显示:
test: JPEG image data, JFIF standard 1.00
额外提示:如果担心vi的编码设置干扰,可以在打开文件时指定二进制模式:vi -b test,这样vi会以纯二进制方式处理文件,避免不必要的编码转换。
内容的提问来源于stack exchange,提问作者hap78




