使用“xxd”进行二进制到ASCII转换

5

我知道如何将十六进制转换为ASCII。

echo 54 58 72 56 等 | xxd -r -p -> 将生成ASCII输出

但是我正在努力将以下二进制代码转换为ASCII。

01000001 01110010 01100101 01101110 00100111 01110100 00100000 01111001 01101111 01110101 00100000 01100001 00100000 01101100 01101001 01110100 01110100 01101100 01100101 00100000 01110011 01101000 01101111 01110010 01110100 00100000 01100110 01101111 01110010 00100000 01100001 00100000 01110011 01110100 01101111 01110010 01101101 00100000 01110100 01110010 01101111 01101111 01110000 01100101 01110010 00111111 00001101 00001010

我需要使用“xxd”或类似的尽可能短的命令来完成此操作。

谢谢您提前!


如果您对@kabanus的回答感到满意,请接受他/她的答案。 - Ubdus Samad
2个回答

7

如果您想继续使用xxd,那么您需要先将每个二进制数转换为十进制数。如果您正在使用bash,并且x包含您的二进制字符串,则:

for a in $x; do printf "%x" $((2#$a)); done | xxd -r -p 

$((2#$a)) 是Bash中的二进制转十进制,printf将其转换为十六进制。然后将其传递到xxd - 就可以获得之前所获得的内容。

你是暴风trooper, 不是有点矮了吗?

如果字符串包含在文件中,请逐行读取,然后逐个单词读取。另一个选项是仅使用printf,但然后需要使用八进制数字,因此需要两次使用printf

for a in $x; do printf \\$(printf "%o" $((2#$a))); done

实际上,最后一种方法也可以使用hex完成,只需使用\\x代替\\,则%o将恢复为%x


谢谢!这就是我在寻找的东西。 - Seba
@Seba 这里不需要感谢。如果答案有助于未来读者,就接受它吧,如果你非常有信心的话也可以点赞。祝好运。 - kabanus

1
一行代码解决此问题:

data=$(cat file.in); echo $(printf '%x\n' "$((2#$data))") | xxd -r -p > file.out

问题在于printf似乎有一个字符限制,可以通过将数据分成块使之可被处理,例如每8个字节一组(在我的Ubuntu 16.04.7上)。
一种解决方法是逐个字符(字节序列)或从文件中逐行循环。
data=$(cat file.in); for byte in $data; do echo $(printf '%x\n' "$((2#$byte))"); done | xxd -r -p

不需要将其转换为八进制或在分离单词之前逐行读取。

字典/数据库/数组可能是另一种但较慢的解决方案(如果你有足够的内存或不想将数据存储在文件中):

D2B=(01000001 01110010 01100101 01101110 00100111 01110100 00100000 01111001 01101111 01110101 00100000 01100001 00100000 01101100 01101001 01110100 01110100 01101100 01100101 00100000 01110011 01101000 01101111 01110010 01110100 00100000 01100110 01101111 01110010 00100000 01100001 00100000 01110011 01110100 01101111 01110010 01101101 00100000 01110100 01110010 01101111 01101111 01110000 01100101 01110010 00111111 00001101 00001010); 
count=${#D2B[@]}; 
run='D2C=('${D2B[@]}'); for word in {0..'$count'}; do echo -n $(printf '%x' "$((2#${D2C[$word]}))"); done;';
echo "$run" | bash | xxd -r -p

或者将字符串解决方案传递给数组以获得更快的响应:

dat="01000001 01110010 01100101 01101110 00100111 01110100 00100000 01111001 01101111 01110101 00100000 01100001 00100000 01101100 01101001 01110100 01110100 01101100 01100101 00100000 01110011 01101000 01101111 01110010 01110100 00100000 01100110 01101111 01110010 00100000 01100001 00100000 01110011 01110100 01101111 01110010 01101101 00100000 01110100 01110010 01101111 01101111 01110000 01100101 01110010 00111111 00001101 00001010"; 
count=$(echo $dat ^| wc -w); 
run='D2C=('$dat'); for word in {0..'$count'}; do echo -n $(printf '%x' "$((2#${D2C[$word]}))"); done;'; 
echo "$run" | bash | xxd -r -p

或者仅字符串解决方案(无数组):
dat="01000001 01110010 01100101 01101110 00100111 01110100 00100000 01111001 01101111 01110101 00100000 01100001 00100000 01101100 01101001 01110100 01110100 01101100 01100101 00100000 01110011 01101000 01101111 01110010 01110100 00100000 01100110 01101111 01110010 00100000 01100001 00100000 01110011 01110100 01101111 01110010 01101101 00100000 01110100 01110010 01101111 01101111 01110000 01100101 01110010 00111111 00001101 00001010"; 
count=$(echo $dat ^| wc -w); 
run='D2C="'$dat'"; for word in {0..'$count'}; do byte=${D2C:$((word+8*word)):8}; echo -n $(printf '%x' "$((2#$byte))"); done;'; 
echo "$run" | bash | xxd -r -p

在Ubuntu 16.04.7上进行了测试


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接