【问题标题】:How to create a hex dump of file containing only the hex characters without spaces in bash?如何在bash中创建仅包含十六进制字符而不包含空格的文件的十六进制转储?
【发布时间】:2011-02-06 13:41:44
【问题描述】:

如何使用 bash 在 Linux 中创建二进制文件的未修改十六进制转储? odhexdump 命令都在转储中插入空格,这并不理想。

有没有办法在输出中简单地编写一个包含所有十六进制字符、减去空格或换行符的长字符串?

【问题讨论】:

标签: linux bash hex


【解决方案1】:
xxd -p file

或者,如果您想在一行中全部显示:

xxd -p file | tr -d '\n'

【讨论】:

  • fyi 要反转这个过程:xxd -r -ps hexascii.txt 文件(可以有或没有换行符)
【解决方案2】:

格式化字符串可以使 hexdump 的行为完全符合您的要求(完全没有空格,逐字节):

hexdump -ve '1/1 "%.2x"'

1/1 表示“每种格式都应用一次并占用一个字节”,"%.2x" 是实际的格式字符串,就像在 printf 中一样。在这种情况下:2 个字符的十六进制数字,如果较短则前导零。

【讨论】:

  • 你需要一个-v 否则它会丢弃重复的字节并用星号替换它们。
  • 我想知道 hexdump 本身是否能够(仅)将换行符附加到输出的末尾。(; echo 的明显附加使其无法用作 bash 别名)
  • 我的别名:alias to_hex="hexdump -ve '1/1 \"%.2x\"' && echo"
  • 迭代次数和字节数默认为1,所以1/1可以省略,留下hexdump -ve '"%.2x"'
  • @mykhal,如果您知道输出中的字节数,这是可能的。假设您使用 hexdump 仅输出 13 个前字节:hexdump -n 13 -e '13/1 "%.2x" "\n"'
【解决方案3】:

这似乎取决于od的版本细节。在 OSX 上,使用这个:

od -t x1 -An file |tr -d '\n '

(打印为十六进制字节类型,没有地址。当然,随后空格被删除。)

【讨论】:

  • 我也会在这个上下文中添加-v,否则它会跳过*的重复。
【解决方案4】:

Perl 单行:

perl -e 'local $/; print unpack "H*", <>' file

【讨论】:

  • 已验证。匹配“xxd -p 文件 | tr -d '\n'”。
  • fyi 要反转这个过程: perl -e 'local $/;打印包 "H*", ' file
  • “本地$/”是不必要的。
  • 更新到最后一条评论:“pack”不需要“local $/”。对于解包,您需要它,但也可以输入“undef $/”。 $/ 是行分隔符(默认 NL)。 undefined 将其置于 slurp 模式。因此,在字符串上下文中引用的 会拉取整个二进制文件而不会将其解析为行。
  • 替代形式:perl -e 'print unpack "H*", join("", )'
【解决方案5】:

其他答案更可取,但对于纯 Bash 解决方案,我已修改 my answer here 中的脚本,以便能够输出表示文件内容的连续十六进制字符流。 (它的正常模式是模拟hexdump -C。)

【讨论】:

    【解决方案6】:

    我认为这是最广泛支持的版本(仅需要 POSIX 定义的 trod 行为):

    cat "$file" | od -v -t x1 -A n | tr -d ' \n'
    

    这使用od 将每个字节打印为没有地址的十六进制而不跳过重复的字节,并使用tr 删除输出中的所有空格和换行符。请注意,这里甚至不会发出尾随换行符。 (cat 有意允许多核处理,其中cat 可以等待文件系统,而od 仍在处理先前读取的部分。单核用户可能希望用&lt; "$file" od ... 替换它以节省启动一个额外的进程。)

    【讨论】:

      【解决方案7】:

      此代码生成一个“纯”十六进制转储字符串,它运行速度比所有 给出的其他示例。 它已经在 1GB 填充二进制零和所有换行符的文件上进行了测试。 它不依赖于数据内容,读取 1MB 记录而不是行。

      perl -pe 'BEGIN{$/=\1e6} $_=unpack "H*"'
      

      数十次计时测试表明,对于 1GB 文件,以下这些其他方法较慢。 所有测试都运行将输出写入文件,然后通过校验和进行验证。 测试了三个 1GB 输入文件:所有字节、所有二进制零和所有 LF。

      hexdump -ve '1/1 "%.2x"'                    #  ~10x  slower
      od -v -t x1 -An | tr -d "\n "               #  ~15x  slower
      xxd -p | tr -d \\n                          #   ~3x  slower
      perl -e 'local \$/; print unpack "H*", <>'  # ~1.5x  slower
      - this also slurps the whole file into memory
      

      要反转这个过程:

      perl -pe 'BEGIN{$/=\1e6} $_=pack "H*",$_'
      

      【讨论】:

        【解决方案8】:

        tldr;

        $ od -t x1 -A n -v <empty.zip | tr -dc '[:xdigit:]' && echo 
        504b0506000000000000000000000000000000000000
        $
        

        说明:

        使用od 工具打印单个十六进制字节 (-t x1) --- 没有地址偏移 (-A n) 并且没有省略重复的“组”(-v) --- 来自empty.zip,它有被重定向到标准输入。将其传送到tr,它会删除(-d)十六进制字符集('[:xdigit:]')的补码(-c)。您可以选择打印尾随换行符 (echo),就像我在此处所做的那样,将输出与下一个 shell 提示符分开。

        参考资料:

        【讨论】:

          【解决方案9】:

          您可以为此目的使用 Python:

          python -c "print(open('file.bin','rb').read().hex())"
          

          ...file.bin 是您的文件名。

          说明:

          1. rb(读取二进制)模式打开file.bin
          2. 读取内容(返回为bytes 对象)。
          3. 使用bytes 方法.hex(),它返回不带空格或换行符的十六进制转储。
          4. 打印输出。

          【讨论】:

            猜你喜欢
            • 2023-04-08
            • 2014-03-26
            • 2014-10-07
            • 2018-06-16
            • 2019-12-26
            • 2012-05-23
            • 2012-06-05
            • 1970-01-01
            • 2011-06-01
            相关资源
            最近更新 更多