我知道如何将十六进制转换转换为ASCII。
echo 54 58 72 56 etc | 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'或与可能的命令一样短的方法来执行此操作。
提前谢谢!
答案 0 :(得分:1)
如果您想坚持xxd
,那么您需要先将每个二进制数转换为十进制数。如果您使用的是bash
,而x
包含的是二进制字符串,那么:
for a in $x; do printf "%x" $((2#$a)); done | xxd -r -p
$((2#$a))
是bash中的二进制到十进制转换,printf
会将此转换为十六进制。然后将其传送到xxd
- 并获得之前的结果。
对于风暴骑兵来说,你不是有点短吗?
如果字符串包含在文件中,则逐行读取,然后逐字逐句读取。另一种选择是仅使用printf
,但是您需要八进制数,因此使用printf
两次:
for a in $x; do printf \\$(printf "%o" $((2#$a))); done
实际上最后一个也可以使用hex
完成,只需使用而不是\\
\\x
而%o
将恢复为%x
。
答案 1 :(得分:0)
解决此问题的单衬是:
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 上测试