【问题标题】:Bash decimal to base 62 conversionBash 十进制到 base 62 的转换
【发布时间】:2013-01-06 11:00:37
【问题描述】:

我想反转下面bash命令执行的操作:

$ echo $((62#a39qrT))
9207903953

即将 十进制 9207903953 转换为 base 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 输入。

【问题讨论】:

标签: bash shell base-conversion bc


【解决方案1】:

我非常感谢您提出的解决方案,而且我想没有办法直接使用 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

【讨论】:

  • 关键点是消除前导零并强制基数为10,使用$$((10#$i))。这里的字符串$(bc &lt;&lt;&lt; "...") 很好,但不是强制性的。
  • 对称base62解码函数如下:function base62_decode() { echo $((62#$1)) }
  • @jsears 如果输入太长,这不起作用,你有二进制的恭维,它返回一个负数而不是正确的十进制数。你有替代这种方法的方法来从 base-62 转换为十进制吗?
【解决方案2】:
function base62encode() {
  bc<<<"obase=62;$1" | awk '{for (i=1; i<=NF; i++) printf "%c", $i+(($i<10)?48:(($i<36)?87:29))}'
}
  • bc&lt;&lt;&lt;"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 相同:你应该使用相同的帐户,那么你可以编辑你的答案。如果不是:在我看来,编辑应该是评论。
【解决方案3】:

或者没有 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
  • 您指定了一个倒置的 base-2 数字,它实际上按预期工作。
  • 嘿,完美代码几乎 :) 01234 65 789 如果有人想用它来测试它是否有效,最好颠倒这个 echo $((62#$(base62encode 1624429385))) 应该输出与输入相同;D
【解决方案4】:

使用gforthtr的任意base10到baseX的转换函数,(需要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

【讨论】:

    猜你喜欢
    • 2010-11-10
    • 2017-09-04
    • 2011-02-19
    • 2019-05-10
    • 2013-01-24
    • 2014-09-20
    • 2012-06-22
    • 2012-05-03
    相关资源
    最近更新 更多