Bash - 将整数转换、编码为缩短的字母数字字符串

Bash - 将整数转换、编码为缩短的字母数字字符串

BASH 中有没有办法将整数转换为缩短的字母数字字符串?

如果我开始,让我们说var=20171019194210。我想要得到类似以下的东西。

echo "$var" | encoding
a4f5e6g

进而:

echo "$var" | decoding
20171019194210

我发现了一些东西Stackoverflow 上的 Python;但是,如果可能的话,我更愿意将 BASH 与 GNU 工具的任意组合一起使用awk

我正在尝试通过创建时间戳来为文件创建唯一 ID,如下所示。

date +"%Y%m%d%H%M%S"

然后,我将此时间戳包含在文件名中,以识别系统上的文件,而无需使用整个文件名,或者无需使用文件名的其余部分即可识别该文件。

我现在想缩短或编码这个整数,使其在长度方面更可用,但以同样的方式可以重新计算时间戳值。

答案1

这是在 bash 中,所以速度会很慢。它将 2 个数字映射到 1 个字符。它使用 base64 字母表,因此只能容纳 0 到 63 之间的数字——小时、分钟、秒、天和月都可以,但到 2064 年将停止工作。map用更多字符来扩展它。

declare -a map=(
    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 
    a b c d e f g h i j k l m n o p q r s t u v w x y z 
    0 1 2 3 4 5 6 7 8 9 + /
)

declare -A revmap
for ((i=0; i<${#map[@]}; i++)); do revmap[${map[i]}]=$(printf "%02d" $i); done

encode() { 
    local i result=""
    for ((i=0; $i < ${#1}; i+=2)); do 
        # specifies base 10 numbers to prevent attempted interpretation
        # of invalid octal numbers 08,09
        result+=${map[10#${1:i:2}]:-"?"}
    done
    echo "$result"
}

decode() { 
    local i result=""
    for ((i=0; i<${#1}; i++)); do 
        result+=${revmap[${1:i:1}]:-"??"}
    done
    echo "$result"
}

encode 20171019194210              # => URKTTqK
decode $(encode 20171019194210)    # => 20171019194210

encode 20671019194210              # => U?KTTqK
# .......^^
decode "$(encode 20671019194210)"  # => 20??1019194210

答案2

您预计会短多少?使用十六进制表示将使给定数字少 2 个字符。对于较长的数字,可能会节省更多。

LONGER=20171019194210                                #compare: 
SHORTER=$(printf "%X\n" $LONGER)                     #12586E6F0F62
RESTORED=$(echo "obase=10; ibase=16; $SHORTER" | bc) #20171019194210

相关内容