我正在尝试将十六进制字符串转换为二进制。我正在使用:
echo "ibase=16; obase=2; $line" | BC_LINE_LENGTH=9999 bc
它正在截断前导零。也就是说,如果十六进制字符串是4F
,它将转换为1001111
,如果是0F
,则会转换为1111
。我需要01001111
和00001111
我该怎么办?
答案 0 :(得分:3)
bc
的输出是正确的;它根本不是你的想法(但它是bc
的设计者所想到的)。如果你将十六进制4F
转换为十进制,你不会期望得到079,是吗?如果输出基数是二进制的,为什么要得到前导零?简短的回答:你不应该这样,所以bc
不会发出它们。
如果必须使二进制输出为8位的倍数,则可以使用其他工具添加适当数量的前导零,例如awk
:
awk '{ len = (8 - length % 8) % 8; printf "%.*s%s\n", len, "00000000", $0}'
答案 1 :(得分:1)
你可以在python中完成:
line=4F
python -c "print ''.join([bin(int(i, 16))[2:].zfill(4) for i in '$line'])"
结果:
'01001111'
答案 2 :(得分:1)
你可以像这样管道awk
:
echo "ibase=16; obase=2; $line" | BC_LINE_LENGTH=9999 bc | awk '{ printf "%08d\n", $0 }'
答案 3 :(得分:1)
纯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
答案 4 :(得分: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;'
答案 5 :(得分:0)
您可以使用 seq 和 sed 来帮助您填写:
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
答案 6 :(得分: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