[Shell] 10進数を62進数に変換するライブラリ

2018/04/29

Shell テクノロジー プログラミング 特集

t f B! P L
すでに、PHP,javascript,python,rubyで構築した62進数ライブラリですが、ターミナルで使いたいので、bash(shell)で書いて見ました。 これまで、62進数は、時計フォーマットの圧縮に最適ということを伝えてきましたが、大きな桁数に対しても有効なので、たくさんの桁の数値を扱う場合はまあまあの圧縮率があります。 ただし、デメリットとして、内部loopが増えると、処理速度はとても遅くなるので、ログ解析などでレコード単位で使ってしまうと眠くなるほど遅延する事があるので、要注意です。 あと、もうひとつデメリットとしては、エンコードした後の62進数文字列は、ファイル名にした場合、10進数とは昇順の並びが変わってしまうので、若い日付順などとして使いたい場合は気をつけないとバグの元になります。

ソースコード

#!/bin/bash decimal62_char="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; function decimal62_encode(){ num=$1 str=() cn=${#decimal62_char} while [ $num -ne 0 ] do a1=`expr $num / $cn`; a3=`expr $a1 \* $cn` a2=`expr $num \- $a3` s=${decimal62_char:$a2:1} str=($s "${str[@]}") num=$a1 done res="$(IFS=; echo "${str[*]}")" echo $res } function decimal62_decode(){ str=$1 declare -A chrs cn=${#decimal62_char} max1=`expr $cn \- 1` for i in `seq 0 $max1` do s=${decimal62_char:$i:1} chrs[$s]=$i done num=0 max2=`expr ${#str} \- 1` for i in `seq 0 $max2` do a=`expr $i \+ 1` s=${str:`expr $a \* -1`:1} p=$(($cn**$i)) num=`expr $num + ${chrs["$s"]} \* $p` done echo $num } enc=(`decimal62_encode 20180425231245`) dec=(`decimal62_decode $enc`) echo $enc echo $dec 実行 $ bash decimal62.sh > 5JhPVGod > 20180425231245 コマンドとして使いたい場合は、内部の実行行をとって、encodeとdecodeを分けてbinフォルダなどに入れてお使いください。

適当に解説

shellは関数の扱いや、変数、配列の扱いが非常にやりにくいので、構文に気をつけて行いました。 変数は宣言時に"hoge=123"として、それを参照して使うときは"echo $hoge"となります。 通常プログラムをやっている人なら、違和感ありまくりでしょうね。 あと、四則演算を行う際に都度"expr"関数を使ってやらなければいけないので、この点も慣れないうちはまあまあめんどくさいでしょう。 ちなみに、今回べき乗処理を行なっていて、"$((a**b))"という書き方をしています。 このやり方はまあまあ使いやすかったのですが、四則演算との整合性は無視して記述してしまいました。 あと、shellの時に毎回書いてますが、関数の引渡し値を"$1"として受け取っているのがいまだにどうしても納得いかず、なぜ"function()"という書き方をさせておいて、$1で受け取るのか、不思議です。 プログラムの構文としては、非常に扱いづらいのはいうまでもありません。 まあ愚痴はその辺にして、慣れてしまえばこれはこれでいいとしましょう。

多言語対応

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ