我看到了一些奇怪的东西。 我尝试使用 Bash Shell 将十六进制转换为十进制。
我使用了非常简单的命令。
$ g_receiverBeforeToken=1158e460913d00000
$ echo $((16#$g_receiverBeforeToken))
1553255926290448384
正如大家所知,这个结果应该是“20000000000000000000”。
当我输入其他任何十六进制数时,都是正确的。但只有1553255926290448384是奇怪的。
我看到了一些奇怪的东西。 我尝试使用 Bash Shell 将十六进制转换为十进制。
我使用了非常简单的命令。
$ g_receiverBeforeToken=1158e460913d00000
$ echo $((16#$g_receiverBeforeToken))
1553255926290448384
正如大家所知,这个结果应该是“20000000000000000000”。
当我输入其他任何十六进制数时,都是正确的。但只有1553255926290448384是奇怪的。
这里不仅仅是限制在那个数字上,而是任何大于7fffffffffffffff的数字,因为它使用了64位整数,这是最大的一个。超过这个的16位数字会被包装并变成负数(因为有符号整数采用二进制补码表示法):
$ echo $((16#7fffffffffffffff))
9223372036854775807
$ echo $((16#7fffffffffffffff + 1))
-9223372036854775808
$ echo $((16#8000000000000000))
-9223372036854775808
过去的ffffffffffffffff(也称为-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
ival="${1^^}"
时,出现了错误的替换错误。 - qodeninjabash --version
显示什么?在man bash
中,${parameter^^pattern}
位于“参数扩展”的更广泛部分下。它已经成为bash的一部分了一段时间。您确定没有使用#!/bin/sh
或以sh scriptname
运行它吗?另外,echo $SHELL
显示什么? - David C. Rankintr
,现在似乎可以工作了。还有一个问题,我对bc
不太熟悉,但如果我想将十六进制字符串转换为基于62个字母数字的字符串,我该如何使用您的脚本?具体来说,我正在尝试将md5哈希缩短为较短的基于62个字符的字符串(并稍后将其恢复为md5)。 - qodeninjabc
。例如,printf "obase=%d; ibase=%d; %s\n" $ob $ib $val | bc
,其中 ob=62
,ib=10
,而 val
是您想要从十进制转换为六十二进制的任何值。(根据需要调整您的 ib
) - David C. Rankin
1553255926290448383
没问题吗?顺便问一下,你知道20000000000000000000
大于 2**64 吗?你的机器字长可能是 64 位。64 位是 16 个十六进制数字。1158e460913d00000
是 17 个十六进制数字。 - lurker