BASHで整数を短縮された英数字文字列に変換する方法はありますか?
開始するとvar=20171019194210
。私は次のようなものを取得したいと思います。
echo "$var" | encoding
a4f5e6g
それから:
echo "$var" | decoding
20171019194210
私は何かを見つけましたStackoverflowのPython;しかし、可能であれば、GNUツールを組み合わせてBASHを使用することをお勧めします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
どのくらい短くなると思いますか? 16進表現を使用すると、与えられた数字の2文字が短くなります。数字が長いと節約効果が大きくなることがあります。
LONGER=20171019194210 #compare:
SHORTER=$(printf "%X\n" $LONGER) #12586E6F0F62
RESTORED=$(echo "obase=10; ibase=16; $SHORTER" | bc) #20171019194210