在bash中进行十六进制转二进制的转换

20

我正在尝试使用Bash将一系列十六进制字节转换为二进制,但是以下代码返回“(standard_in) 1: syntax error”错误:

for j in c4 97 91 8c 85 87 c4 90 8c 8d 9a 83 81
do
        BIN=$(echo "obase=2; ibase=16; $j" | bc )
        echo $BIN
done

我用相似的方法将十进制转为二进制,这个方法运行得非常好:

for i in {0..120}
do
        KEYBIN=$(echo "obase=2; ibase=10; $i" | bc)
        echo $KEYBIN
done

有人知道为什么这段代码使用十进制可以运行,但用十六进制就不行吗?我认为语法十分相似(除非我漏掉了什么极其困难的东西)。


可能是Linux Shell脚本:十六进制字符串转字节的重复问题。 - Ciro Santilli OurBigBook.com
4个回答

22

BC对于十六进制值的大小写比较敏感,将其改为大写后它就能正常工作。

for j in C4 97 91 8C 85 87 C4 90 8C 8D 9A 83 81
do
        BIN=$(echo "obase=2; ibase=16; $j" | bc )
        echo $BIN
done

输出:

11000100
10010111
10010001
10001100
10000101
10000111
11000100
10010000
10001100
10001101
10011010
10000011
10000001

所以这真的只是一个简单的错误。感谢您指出,现在运行得很好。 - fragman
很高兴能够帮助,BC是一款很棒的工具,但也有些小问题需要了解 :-) - Fredrik Pihl
1
有人知道如何将bc的输出填充到特定位数吗?这在上面的示例中并不需要,但请尝试使用00作为输入运行循环。 - Chaos_99
看一下 length 函数。"长度函数的值是表达式中有效数字的数量。" - Fredrik Pihl
以下是一个只有一个值的示例: echo "obase=2; ibase=16; EF" | bc - Harsha Laxman

15
我想到了这个: printf将内容转换为十六进制,xxd -r -p将ASCII十六进制流转换为实际的二进制值
使用hexdump进行转储以验证它是否工作...
我想到了这个: printf将内容转换为十六进制,xxd -r -p将ASCII十六进制流转换为实际的二进制值。使用hexdump进行输出以证明其有效性...
printf "%016x" 53687091200 | xxd -r -p | hexdump -C

可以工作。但是,xxd 不允许我将 -r-p 组合成 -rp,目前我可以接受这种情况。 - Harry
多么不像Unix啊,但我想这就是它的本质。你可以在GitHub上开一个问题 :-) - stu
答案真是令人惊叹。 - undefined

7
这是我使用的脚本:
#!/bin/bash
# SCRIPT:  hex2binary.sh
# USAGE:   hex2binary.sh Hex_Number(s)
# PURPOSE: Hex to Binary Conversion. Takes input as command line
#          arguments.
#####################################################################
#                      Script Starts Here                           #
#####################################################################

if [ $# -eq 0 ]
then
    echo "Argument(s) not supplied "
    echo "Usage: hex2binary.sh hex_number(s)"
else
    echo -e "\033[1mHEX                 \t\t BINARY\033[0m"

    while [ $# -ne 0 ]
    do
        DecNum=`printf "%d" $1`
        Binary=
        Number=$DecNum

        while [ $DecNum -ne 0 ]
        do
            Bit=$(expr $DecNum % 2)
            Binary=$Bit$Binary
            DecNum=$(expr $DecNum / 2)
        done

        echo -e "$Number              \t\t $Binary"
        shift
        # Shifts command line arguments one step.Now $1 holds second argument
        unset Binary
    done

fi

1
注意事项:十六进制数字必须以“0x”开头,而HEX列实际上列出的是十进制值。但感谢您提供了一个纯Bash解决方案来回答“如何在Bash中...”的问题!有时这确实是人们正在寻找的。您并不总是可以依赖像bc这样的工具的存在。 - system PAUSE
我使用的bash版本(4.4.12)不需要在十六进制数字前加前缀。但是该脚本无法正确处理0,您需要在最后一个echo调用中将$Binary替换为${Binary:-0} - untore

2

试试这个:

for j in c4 97 91 8c 85 87 c4 90 8c 8d 9a 83 81
do
    BIN=$(echo "obase=2; ibase=16; ${j^^}" | bc )
    echo $BIN
done

还有其他答案可以回答提问者的问题,而且它们是一段时间之前发布的。当您发布答案时,请确保添加一个新的解决方案或更加详细的解释,特别是在回答旧问题时。参见:如何撰写好的答案? - help-info.de
3
接受的答案表示需要大写并更改输入数据。这个答案保留了数据(通常不可控),而是使用${j^^}将数据转换为大写,因此这是更好的解决方案,但缺乏解释。 - NiKiZe

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