在 bash 命令行中将十六进制字符串转换为 ascii

Posted

技术标签:

【中文标题】在 bash 命令行中将十六进制字符串转换为 ascii【英文标题】:Conversion hex string into ascii in bash command line 【发布时间】:2012-10-21 01:13:04 【问题描述】:

我有很多这种类型的字符串,我想找到一个命令将其转换为 ascii,我尝试使用 echo -eod,但没有成功。

0xA7.0x9B.0x46.0x8D.0x1E.0x52.0xA7.0x9B.0x7B.0x31.0xD2

【问题讨论】:

这看起来不像 ASCII。 ASCII 未定义大于 0x7f 的值。 你的意思是它是二进制的吗? 你的意思是 int/binary 而不是 ASCII?您显示的值大于 ASCII 范围... 您希望从示例字符串中得到什么? 我希望有一个可打印的字符串,但它不是……它应该是一个明文密码。但从你所说的我猜是加密或散列(二进制版本) 【参考方案1】:

此代码会将文本 0xA7.0x9B.0x46.0x8D.0x1E.0x52.0xA7.0x9B.0x7B.0x31.0xD2 转换为具有等效值的 11 字节流。这些字节将被写入标准输出。

TESTDATA=$(echo '0xA7.0x9B.0x46.0x8D.0x1E.0x52.0xA7.0x9B.0x7B.0x31.0xD2' | tr '.' ' ')
for c in $TESTDATA; do
    echo $c | xxd -r
done

正如其他人指出的那样,这不会产生可打印的 ASCII 字符串,原因很简单,指定的字节不是 ASCII。您需要发布更多关于您如何获得此字符串的信息,以便我们帮助您。

它是如何工作的: xxd -r 将十六进制数据转换为二进制(如反向 hexdump)。 xxd 要求每行以该行第一个字符的索引号开始(在某事上运行 hexdump 并查看每行如何以索引号开始)。在我们的例子中,我们希望该数字始终为零,因为每次执行只有一行。幸运的是,我们的数据在每个字符之前已经有零作为 0x 符号的一部分。小写的 x 会被 xxd 忽略,所以我们要做的就是将每个 0xhh 字符通过管道传递给 xxd 并让它完成工作。

tr 将句点转换为空格,以便 for 将其正确拆分。

【讨论】:

在新的 Redhat linux(使用 ksh)上使用 xxd --version = xxd V1.10 27oct98 不适用于我。我只得到一个 § char。 这正是我得到的。数据不是文本,所以不能很好地打印出来。要以可打印的形式查看它,请将我的代码放入 bash 函数中,例如 danstest() ... 。然后,调用该函数并将输出通过管道传输到 hexdump -C。这将逐字节显示我的代码中的数据。 酷。你可以做 ` ... 完成 | hexdump -C`,不需要函数。祝大家好运。 谢谢!这是sh 上唯一对我有用的东西。 需要使用xxd -r -p从“xxd V1.10 27oct98”获取字符串输出【参考方案2】:

echo -e 一定是因为错误的转义而失败了。 以下代码在 your_program with arguments 的类似输出上对我来说很好:

echo -e $(your_program with arguments | sed -e 's/0x\(..\)\.\?/\\x\1/g')

但请注意,您的原始十六进制字符串包含不可打印的字符。

【讨论】:

【参考方案3】:

这对我有用。

$ echo 54657374696e672031203220330 | xxd -r -p
Testing 1 2 3$

-r 告诉它将十六进制转换为 ascii,而不是其正常模式的相反操作

-p 告诉它使用纯格式。

【讨论】:

pbpaste | xxd -rp 来自 Mac 上的 Homebrew 不起作用,但 pbpaste | xxd -r -p 起作用了.....【参考方案4】:

你可以使用这样的东西。

$ cat test_file.txt
54 68 69 73 20 69 73 20 74 65 78 74 20 64 61 74 61 2e 0a 4f 6e 65 20 6d 6f 72 65 20 6c 69 6e 65 20 6f 66 20 74 65 73 74 20 64 61 74 61 2e

$ for c in `cat test_file.txt`; do printf "\x$c"; done;
This is text data.
One more line of test data.

【讨论】:

我正在尝试从看起来像十进制的游戏(精英:危险)中解码神秘数据,这似乎有效(使用\\ 而不是\x)。 (:【参考方案5】:

您提供的值是 UTF-8 值。设置时,数组:

declare -a ARR=(0xA7 0x9B 0x46 0x8D 0x1E 0x52 0xA7 0x9B 0x7B 0x31 0xD2)

会被解析打印出每个值的明文字符。

for ((n=0; n < $#ARR[*]; n++)); do echo -e "\u$ARR[$n]//0x/"; done

输出会产生一些可打印的字符和一些不可打印的字符,如下所示:

使用echo 命令将十六进制值转换为明文:

echo -e "\x<hex value here>"

对于使用 echo 命令将 UTF-8 值转换为纯文本:

echo -e "\u<UTF-8 value here>"

然后使用echo 命令将八进制转换为纯文本:

echo -e "\0<octal value here>"

如果您有不熟悉的编码值,请花时间检查常见编码方案中的范围,以确定值属于哪种编码。然后从那里开始转换。

【讨论】:

【参考方案6】:

编写如下脚本:

#!/bin/bash

echo $((0x$1)).$((0x$2)).$((0x$3)).$((0x$4))

例子:

sh converthextoip.sh c0 a8 00 0b

结果:

192.168.0.11

【讨论】:

【参考方案7】:

你可以使用xxd:

$cat hex.txt
68 65 6c 6c 6f
$cat hex.txt | xxd -r -p
hello

【讨论】:

如果您可以访问 xxd,这里的最佳答案。

以上是关于在 bash 命令行中将十六进制字符串转换为 ascii的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Bash 中将字符串从大写转换为小写? [复制]

如何在 DB2 AS/400 中将十进制字段转换为日期字段?

在bash中将科学记数法转换为十进制

在 bash/perl 中将科学记数法转换为十进制(不是整数)

在Objective C(可可)中将十六进制数据字符串转换为NSData

在R中将十六进制转换为十进制