在shell脚本中将二进制数据转换为十六进制

发布于 2024-11-14 19:43:57 字数 169 浏览 7 评论 0原文

我想将二进制数据转换为十六进制,仅此而已,没有花哨的格式等等。 hexdump 似乎太聪明了,它对我来说“过度格式化”。我想从 /dev/random 中获取 x 个字节并将它们作为十六进制传递。

最好我只想使用标准的 Linux 工具,这样我就不需要在每台机器上安装它(有很多)。

I want to convert binary data to hexadecimal, just that, no fancy formatting and all. hexdump seems too clever, and it "overformats" for me. I want to take x bytes from the /dev/random and pass them on as hexadecimal.

Preferably I'd like to use only standard Linux tools, so that I don't need to install it on every machine (there are many).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

゛时过境迁 2024-11-21 19:43:57

也许使用 xxd:

% xxd -l 16 -p /dev/random
193f6c54814f0576bc27d51ab39081dc

Perhaps use xxd:

% xxd -l 16 -p /dev/random
193f6c54814f0576bc27d51ab39081dc
世态炎凉 2024-11-21 19:43:57

当心!

hexdumpxxd 给出了不同字节顺序的结果!

$ echo -n 

简单解释一下。大尾数与小尾数 :D

\x12\x34' | xxd -p 1234 $ echo -n

简单解释一下。大尾数与小尾数 :D

\x12\x34' | hexdump -e '"%02x"' 3412 $ echo -n

简单解释一下。大尾数与小尾数 :D

\x01\x02' | hexdump -e '/1 "%02x"' 0102

简单解释一下。大尾数与小尾数 :D

Watch out!

hexdump and xxd give the results in a different endianness!

$ echo -n 

Simply explained. Big-endian vs. little-endian :D

\x12\x34' | xxd -p 1234 $ echo -n

Simply explained. Big-endian vs. little-endian :D

\x12\x34' | hexdump -e '"%02x"' 3412 $ echo -n

Simply explained. Big-endian vs. little-endian :D

\x01\x02' | hexdump -e '/1 "%02x"' 0102

Simply explained. Big-endian vs. little-endian :D

梦回梦里 2024-11-21 19:43:57

使用 od (GNU 系统):

$ echo abc | od -A n -v -t x1 | tr -d ' \n'
6162630a

使用 hexdump (BSD 系统):

$ echo abc | hexdump -ve '/1 "%02x"'
6162630a

来自 十六进制转储、od 和 hexdump

“根据您的系统类型,这两个实用程序中的一个或两个都可用 - BSD 系统不推荐使用 od 进行 hexdump,GNU 系统则相反。”

With od (GNU systems):

$ echo abc | od -A n -v -t x1 | tr -d ' \n'
6162630a

With hexdump (BSD systems):

$ echo abc | hexdump -ve '/1 "%02x"'
6162630a

From Hex dump, od and hexdump:

"Depending on your system type, either or both of these two utilities will be available--BSD systems deprecate od for hexdump, GNU systems the reverse."

命比纸薄 2024-11-21 19:43:57

也许您可以用 C 编写自己的小工具,并即时编译它:

int main (void) {
  unsigned char data[1024];
  size_t numread, i;

  while ((numread = read(0, data, 1024)) > 0) {
    for (i = 0; i < numread; i++) {
      printf("%02x ", data[i]);
    }
  }

  return 0;
}

然后从标准输入提供它:

cat /bin/ls | ./a.out

您甚至可以使用 heredoc 语法将这个小 C 程序嵌入到 shell 脚本中。

Perhaps you could write your own small tool in C, and compile it on-the-fly:

int main (void) {
  unsigned char data[1024];
  size_t numread, i;

  while ((numread = read(0, data, 1024)) > 0) {
    for (i = 0; i < numread; i++) {
      printf("%02x ", data[i]);
    }
  }

  return 0;
}

And then feed it from the standard input:

cat /bin/ls | ./a.out

You can even embed this small C program in a shell script using the heredoc syntax.

流殇 2024-11-21 19:43:57

所有的解决方案似乎都很难记住或太复杂。我发现使用 printf 是最短的:

$ printf '%x\n' 256
100

但正如评论中所述,这不是作者想要的,所以公平地说,下面是完整的答案。

...使用上面的方法输出实际的二进制数据流:

printf '%x\n' $(cat /dev/urandom | head -c 5 | od -An -vtu1)

它的作用:

  • printf '%x\n' .... - 打印整数序列,即 printf '%x,' 1 2 3, 将打印 1,2,3,
  • $(...) - 这是获取某些 shell 命令的输出并对其进行处理的方法
  • cat /dev/urandom - 它输出随机二进制数据
  • head -c 5 - 将二进制数据限制为 5 个字节
  • od -An -vtu1 - 八进制转储命令,将二进制转换为十进制

作为测试用例('a' 是 61 十六进制,'p' 是 70 十六进制, ...):

$ printf '%x\n' $(echo "apple" | head -c 5 | od -An -vtu1)
61
70
70
6c
65

或者要测试单个二进制字节,在输入时让我们给出 61 个十进制('=' 字符)来生成二进制数据('\\x%x' 格式即可实现)。上面的命令将正确输出3d(十进制61):

$printf '%x\n' $(echo -ne "$(printf '\\x%x' 61)" | head -c 5 | od -An -vtu1)
3d

All the solutions seem to be hard to remember or too complex. I find using printf the shortest one:

$ printf '%x\n' 256
100

But as noted in comments, this is not what author wants, so to be fair, below is the full answer.

... to use above to output actual binary data stream:

printf '%x\n' $(cat /dev/urandom | head -c 5 | od -An -vtu1)

What it does:

  • printf '%x\n' .... - prints a sequence of integers , i.e. printf '%x,' 1 2 3, will print 1,2,3,
  • $(...) - this is a way to get output of some shell command and process it
  • cat /dev/urandom - it outputs random binary data
  • head -c 5 - limits binary data to 5 bytes
  • od -An -vtu1 - octal dump command, converts binary to decimal

As a testcase ('a' is 61 hex, 'p' is 70 hex, ...):

$ printf '%x\n' $(echo "apple" | head -c 5 | od -An -vtu1)
61
70
70
6c
65

Or to test individual binary bytes, on input let’s give 61 decimal ('=' char) to produce binary data ('\\x%x' format does it). The above command will correctly output 3d (decimal 61):

$printf '%x\n' $(echo -ne "$(printf '\\x%x' 61)" | head -c 5 | od -An -vtu1)
3d
风筝在阴天搁浅。 2024-11-21 19:43:57

如果您需要大流(没有换行符),您可以使用 tr 和 xxd (Vim 的一部分)进行逐字节转换。

head -c1024 /dev/urandom | xxd -p | tr -d 

或者您可以使用 hexdump (POSIX) 逐字查看单词转换。

head -c1024 /dev/urandom | hexdump '-e"%x"'

请注意,区别在于字节顺序。

\n'

或者您可以使用 hexdump (POSIX) 逐字查看单词转换。

请注意,区别在于字节顺序。

If you need a large stream (no newlines) you can use tr and xxd (part of Vim) for byte-by-byte conversion.

head -c1024 /dev/urandom | xxd -p | tr -d 

Or you can use hexdump (POSIX) for word-by-word conversion.

head -c1024 /dev/urandom | hexdump '-e"%x"'

Note that the difference is endianness.

\n'

Or you can use hexdump (POSIX) for word-by-word conversion.

Note that the difference is endianness.

白色秋天 2024-11-21 19:43:57

dd + hexdump 也可以工作:

dd bs=1 count=1 if=/dev/urandom 2>/dev/null  | hexdump -e '"%x"'

dd + hexdump will also work:

dd bs=1 count=1 if=/dev/urandom 2>/dev/null  | hexdump -e '"%x"'
难如初 2024-11-21 19:43:57

有时,如果您针对多个平台,perl5 的可移植性会更好。每个 Linux 发行版和 Unix 操作系统都附带它。您通常可以在容器映像中找到它,而 xxd 或 hexdump 等其他工具不可用。下面是如何在 Perl 中执行相同的操作:

$ head -c8 /dev/urandom | perl -0777 -ne 'print unpack "H*"'
5c9ed169dabf33ab

$ echo -n 

请注意,这会更多地使用 slurp,这会导致 Perl 将整个输入读取到内存中,当输入很大时,这可能不是最佳的。

\x01\x23\xff' | perl -0777 -ne 'print unpack "H*"' 0123ff $ echo abc | perl -0777 -ne 'print unpack "H*"' 6162630a

请注意,这会更多地使用 slurp,这会导致 Perl 将整个输入读取到内存中,当输入很大时,这可能不是最佳的。

Sometimes perl5 works better for portability if you target more than one platform. It comes with every Linux distribution and Unix OS. You can often find it in container images where other tools like xxd or hexdump are not available. Here's how to do the same thing in Perl:

$ head -c8 /dev/urandom | perl -0777 -ne 'print unpack "H*"'
5c9ed169dabf33ab

$ echo -n 

Note that this uses slurp more, which causes Perl to read the entire input into memory, which may be suboptimal when the input is large.

\x01\x23\xff' | perl -0777 -ne 'print unpack "H*"' 0123ff $ echo abc | perl -0777 -ne 'print unpack "H*"' 6162630a

Note that this uses slurp more, which causes Perl to read the entire input into memory, which may be suboptimal when the input is large.

硪扪都還晓 2024-11-21 19:43:57

这三个命令将打印相同的内容 (0102030405060708090a0b0c):

n=12
echo "$a" | xxd -l "$n" -p
echo "$a" | od  -N "$n" -An -tx1 | tr -d " \n" ; echo
echo "$a" | hexdump -n "$n" -e '/1 "%02x"'; echo

鉴于 n=12$a 是从 1 到 26 的字节值:

a="$(printf '%b' "$(printf '\\0%o' {1..26})")"

这可用于获取$n 随机字节值:

xxd -l "$n" -p                   /dev/urandom
od  -vN "$n" -An -tx1            /dev/urandom | tr -d " \n" ; echo
hexdump -vn "$n" -e '/1 "%02x"'  /dev/urandom ; echo

These three commands will print the same (0102030405060708090a0b0c):

n=12
echo "$a" | xxd -l "$n" -p
echo "$a" | od  -N "$n" -An -tx1 | tr -d " \n" ; echo
echo "$a" | hexdump -n "$n" -e '/1 "%02x"'; echo

Given that n=12 and $a is the byte values from 1 to 26:

a="$(printf '%b' "$(printf '\\0%o' {1..26})")"

That could be used to get $n random byte values in each program:

xxd -l "$n" -p                   /dev/urandom
od  -vN "$n" -An -tx1            /dev/urandom | tr -d " \n" ; echo
hexdump -vn "$n" -e '/1 "%02x"'  /dev/urandom ; echo
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文