Bash 十进制转换为 62 进制

12
我想要反转以下命令执行的操作:
$ echo $((62#a39qrT))
9207903953

即将把十进制数9207903953转换为62进制,并保持bash标准的{0..9},{a..z},{A..Z}

我知道可以使用bc实现此操作,但是需要手动转换每个字符。例如,目前我执行以下操作:

BASE62=($(echo {0..9} {a..z} {A..Z}))
for i in $(echo "obase=62; 9207903953" | bc)
do
    echo -n ${BASE62[$i]} #Doesn't work if bc's output contains leading zeroes
done

一定有一种更为简便的方法来做到这一点。你知道更高效的方法吗?

编辑:更改了bc输入。


4个回答

12

我确实很感激你提出的解决方案,我猜用bash也没有其他简单的方法。这里是你忽略的小问题:

BASE62=($(echo {0..9} {a..z} {A..Z}))
for i in $(bc <<< "obase=62; 9207903953"); do
    echo -n ${BASE62[$(( 10#$i ))]}
done && echo

输出:

a39qrT

2
关键点是消除前导零并强制使用$$((10#$i))的十进制,这里字符串$(bc <<< "...")很好但不是必需的。 - Edouard Thiel
2
这是对称的base62解码函数: function base62_decode() { echo $((62#$1)) } - jsears
@jsears 如果输入太长,这种方法就行不通了。你使用的是二进制补码,它返回的是负数而不是正确的十进制数。你有没有其他方法将基数62转换为十进制数? - qodeninja

4
function base62encode() {
  bc<<<"obase=62;$1" | awk '{for (i=1; i<=NF; i++) printf "%c", $i+(($i<10)?48:(($i<36)?87:29))}'
}
  • bc<<<"obase=62;$1"将输入的值转换为00到61之间带有空格前缀的十进制数序列。
  • 然后通过偏移每个数字在ASCII表中的位置,并使用awk的printf函数将其转换为字符。

或者,可以不使用for循环:

function base62encode() {
  bc<<<"obase=62;$1" | awk 'BEGIN{RS=" +"}/./{printf "%c", $1+(($1<10)?48:(($1<36)?87:29))}';
}

如果编辑器Bob和原始作者Bob是同一个人:您应该使用相同的帐户,然后您可以编辑您的答案。如果不是同一个人:在我看来,编辑应该是一条评论。 - Benjamin W.

2

或者不使用bc,并且使用任意进制:

function baseXencode() {
  awk 'BEGIN{b=split(ARGV[1],D,"");n=ARGV[2];do{d=int(n/b);i=D[n-b*d+1];r=i r;n=d}while(n!=0);print r}' "$1" "$2"
}
function base62encode() {
  baseXencode 0123465789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "$1"
}

第一个例子不能正确运行。例如,baseXencode 10 8 返回 0111 - arielf
您指定了一个倒置的二进制数,它实际上按预期工作。 - astorga
嘿,伙计,perfectcode几乎完美了:)01234 65 789 如果有人想使用这个,最好反转一下为了测试它是否有效 echo $((62#$(base62encode 1624429385)))应该输出与输入相同;D - trycatch

1
任意进制10转换为进制X的函数,使用gforthtr实现(tr是必需的,因为gforthbash使用不同的字符打印进制数):
n2b() { gforth -e "$1 $2 base ! . cr bye" | tr '[0-9A-z]' '[0-9a-zA-Z]' ; }
n2b 9207903953 62
n2b 9207903953 61   # Also works with other bases.
n2b 9207903953 3

输出:

a39qrT 
aT1PM8
212202201021222121202

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