6

我正在尝试将十六进制字符串转换为二进制。我正在使用:

echo "ibase=16; obase=2; $line" | BC_LINE_LENGTH=9999 bc

它正在截断前导零。也就是说,如果十六进制字符串是4F,则将其转换为1001111,如果是0F,则将其转换为1111。我需要0100111100001111

我能做些什么?

4

7 回答 7

5

的输出bc是正确的;它根本不是你的想法(但它是设计师的bc想法)。如果您将十六进制转换4F为十进制,您不会期望从中得到 079,对吗?如果输出基数是二进制的,为什么要得到前导零?简短的回答:你不应该,所以bc不会发出它们。

如果必须使二进制输出为 8 位的倍数,则可以使用其他工具添加适当数量的前导零,例如awk

awk '{ len = (8 - length % 8) % 8; printf "%.*s%s\n", len, "00000000", $0}'
于 2012-09-28T04:57:08.723 回答
2

您可以awk像这样使用管道:

echo "ibase=16; obase=2; $line" | BC_LINE_LENGTH=9999 bc | awk '{ printf "%08d\n", $0 }' 
于 2012-09-28T05:16:43.980 回答
2

纯 Bash 解决方案(除了 bc):

paddy()
{
    how_many_bits=$1
    read number
    zeros=$(( $how_many_bits - ${#number} ))
    for ((i=0;i<$zeros;i++)); do
    echo -en 0
    done && echo $number
}

用法:

>bc <<< "obase=2;ibase=16; 20" | paddy 8
00100000
于 2020-08-25T09:32:57.790 回答
1

你可以在python中做到这一点:

line=4F
python -c "print ''.join([bin(int(i, 16))[2:].zfill(4) for i in '$line'])"

结果:

'01001111'
于 2012-09-28T04:36:19.690 回答
0

令人沮丧的是 bc 期望输入为零填充,但不提供类似的输出选项。这是使用 sed 的另一种选择:

sed 's_0_0000_g;    s_1_0001_g;    s_2_0010_g;    s_3_0011_g;
     s_4_0100_g;    s_5_0101_g;    s_6_0110_g;    s_7_0111_g;
     s_8_1000_g;    s_9_1001_g;    s_[aA]_1010_g; s_[bB]_1011_g;
     s_[cC]_1100_g; s_[dD]_1101_g; s_[eE]_1110_g; s_[fF]_1111_g;'
于 2013-02-02T22:27:29.460 回答
0

您可以使用seqsed来帮助您 pād:

function paddington(){
  PADDLE=8; while read IN; do
    seq -f '0' -s '' 1 $PADDLE | \
    sed "s/0\{${#IN}\}\$/$IN/"
  done
}

bc <<< "ibase=16; obase=2; 4F; 1E; 0F" | paddington

输出:

01001111
00011110
00001111
于 2016-09-21T23:34:53.427 回答
0

如果结果的长度不是四的倍数,您可以使用printf零填充结果:

hex_nr=2C8B; hex_len=${#hex_nr}; binary_nr=$(bc <<< "obase=2;ibase=16;$hex_nr"); \
bin_length=$(( hex_len * 4 )); printf "%0${bin_length}d\n" $binary_nr

将导致

0010110010001011

而不是 bc 的输出

10110010001011

于 2020-08-11T17:49:09.877 回答