使用bash将十六进制转换为十进制
我见过一些奇怪的事情。 我试图用bashshell将十六进制转换为dec 我使用了非常简单的命令使用bash将十六进制转换为十进制,bash,Bash,我见过一些奇怪的事情。 我试图用bashshell将十六进制转换为dec 我使用了非常简单的命令 $ g_receiverBeforeToken=1158e460913d00000 $ echo $((16#$g_receiverBeforeToken)) 1553255926290448384 大家都知道,这个结果应该是‘200000000000000000000’ 当我输入其他十六进制数时,它是正确的。但是只有1553255926290448384很奇怪。不仅仅是这个数字,它是超过7fff
$ g_receiverBeforeToken=1158e460913d00000
$ echo $((16#$g_receiverBeforeToken))
1553255926290448384
大家都知道,这个结果应该是‘200000000000000000000’
当我输入其他十六进制数时,它是正确的。但是只有1553255926290448384很奇怪。不仅仅是这个数字,它是超过7fffffffffffffff的任何数字,因为它使用的是64位整数,这是最大的整数。16位数字环绕并变为负数(因为): 经过ffffffffffffff(aka-1),它返回到零:
$ echo $((16#ffffffffffffffff))
-1
$ echo $((16#ffffffffffffffff + 1))
0
$ echo $((16#10000000000000000))
0
最终结果:只有最后16个十六进制数字才有意义;从64位整数表示的高端删除的任何内容:
$ echo $((16#0000000000000010))
16
$ echo $((16#10000000000000010))
16
$ echo $((16#ffffffff0000000000000010))
16
由于1553255926290448384的长度为17位,因此第一位数字将以这种方式删除:
$ echo $((16#1158e460913d00000))
1553255926290448384
$ echo $((16#158e460913d00000))
1553255926290448384
$ echo $((16#121345158e460913d00000))
1553255926290448384
您可以使用
bc
作为基本转换,通过一个简短的脚本来完成您想要做的事情:
#!/bin/bash
## validate sufficient input
test -n "$1" || {
printf "\n error: insufficient input. usage: %s num [obase (2)] [ibase (10)]\n\n" "${0//*\//}"
exit 1
}
## test for help
test "$1" = "-h" || test "$1" = "--help" && {
printf "\n usage: %s num [obase (2)] [ibase (10)] -- to convert number\n\n" "${0//*\//}"
exit 0
}
## validate numeric value given for conversion (bash only test)
ival="${1^^}"
[[ $ival =~ [^0-9A-F] ]] && {
printf "\n error: invalid input. Input must be within upper/lower case hex character set [0-9A-Fa-f]\n\n"
exit 1
}
ob=${2:-2}
ib=${3:-10}
# set obase first before ibase -- or weird things happen.
printf "obase=%d; ibase=%d; %s\n" $ob $ib $ival | bc
示例使用/输出
$ bash hex2dec.sh -h
usage: hex2dec.sh num [obase (2)] [ibase (10)] -- to convert number
以您的例子:
$ bash hex2dec.sh 1158e460913d00000 10 16
20000000000000000000
如果您希望它也是二进制的,也很方便:
$ bash hex2dec.sh 1158e460913d00000 2 16
10001010110001110010001100000100100010011110100000000000000000000
例如,你是说,
1553255926290448383
工作正常?顺便问一下,您是否知道2000000000000000
大于2**64?您机器上的字大小可能是64位。64位是16位十六进制数字1158e460913d00000
是17位十六进制数字。当我在Mac上尝试此操作时,ival=“${1^^}”
出现错误的替换错误,它是bash的一部分,将第一个位置参数中的所有值转换为所有大写。你的mac电脑上显示了什么bash--version
?它位于manbash
标题下${parameter^^pattern}
的参数扩展
的更广泛部分下。一段时间以来,它一直是bash的一部分。您确定没有使用#/bin/sh
或作为sh scriptname
运行它?还有,echo$SHELL
显示了什么?谢谢,是的,这个Mac操作系统是Bash3.2;我认为大写转换只适用于Bash4+。。。在这种情况下,我使用了tr
,现在似乎可以工作了。还有一个问题,我对bc
不太熟悉,但如果我想将十六进制字符串转换为base-62字母数字字符串,我可以如何使用您的脚本?具体地说,我正在尝试将md5散列减少为较短的base-62字符串(稍后再将其还原为md5)。如果您的输入是base-10,并且希望输出base-62,那么您可以再次使用bc
。例如printf“obase=%d;ibase=%d;%s\n”$ob$ib$val | bc
其中ob=62
和ib=10
和val
是要从基数10转换到基数62的任意值。(根据需要调整您的ib
)感谢您的澄清,这确实是我不熟悉bc的问题;首先,我想直接将字符传递给bc;仍然没有弄明白这一点,而是将位置值相加,而不是直接进行转换。
$ bash hex2dec.sh 1158e460913d00000 2 16
10001010110001110010001100000100100010011110100000000000000000000