Perlで0~536870911までの数字を62進数文字列最大5文字に変換したり逆変換したり
スポンサードリンク
0からの連番(シリアル値)を62進数文字列(最大5文字)として暗号化しておいて、使う時に復号してシリアル値に戻すっていうの。普通にやると、文字が順番に代わっていくだけなのでなんだかいたたまれない気持ちになるので、数値を2進数に見立てて、左右ビット反転することで、それっぽくなる。
Filename: crypt62.pl
use strict; use warnings; use Math::BaseCalc; my $calc = Math::BaseCalc->new(digits => 'bin' ); # 2進数 for (my $i = 0; $i < 16; $i++ ){ my $b = $calc->to_base( $i ); my $h = $calc->to_base( _bit_hanten($i) ); my $c = crypt62 ( $i ); my $d = decrypt62( $c ); printf "%2d %4s %32s %5s %2d\n" ,$i, $b, $h, $c, $d; } exit; sub crypt62 { my $n = shift; my $calc = Math::BaseCalc->new( digits => 62 ); # 62進数 #$n ^= 12345678; # XORする場合 $n = _bit_hanten( $n ) >> 3; # ビット左右反転ご3ビット右シフト my $s = $calc->to_base( $n ); # 数値を62進数文字列へ return $s; #return substr "0000$s", -5; # ゼロパディングする場合 } sub decrypt62 { my $s = shift; my $calc = new Math::BaseCalc( digits => 62 ); # 62進数 my $n = $calc->from_base( $s ); # 62進数文字列を数値へ $n = _bit_hanten( $n << 3 ); # 3ビット左シフト後ビット左右反転 #$n ^= 12345678; # XORする場合 return $n; } sub _bit_hanten { # 32ビット左右反転 my $n = shift; $n = ( $n << 16) | ( $n >> 16 ); $n = ( ($n & 0x00ff00ff) << 8 ) | ( ($n & 0xff00ff00) >> 8 ); $n = ( ($n & 0x0f0f0f0f) << 4 ) | ( ($n & 0xf0f0f0f0) >> 4 ); $n = ( ($n & 0x33333333) << 2 ) | ( ($n & 0xcccccccc) >> 2 ); $n = ( ($n & 0x55555555) << 1 ) | ( ($n & 0xaaaaaaaa) >> 1 ); return $n; } __END__
$ perl crypt62.pl 0 0 0 0 0 1 1 10000000000000000000000000000000 iakk8 1 2 10 1000000000000000000000000000000 95aa4 2 3 11 11000000000000000000000000000000 rfuuc 3 4 100 100000000000000000000000000000 4xA52 4 5 101 10100000000000000000000000000000 mHUpa 5 6 110 1100000000000000000000000000000 dCKf6 6 7 111 11100000000000000000000000000000 vN4ze 7 8 1000 10000000000000000000000000000 2gN2w 8 9 1001 10010000000000000000000000000000 kr7mE 9 10 1010 1010000000000000000000000000000 blXcA 10 11 1011 11010000000000000000000000000000 twhwI 11 12 1100 110000000000000000000000000000 6On7y 12 13 1101 10110000000000000000000000000000 oYHrG 13 14 1110 1110000000000000000000000000000 fTxhC 14 15 1111 11110000000000000000000000000000 y3RBK 15 $
変換後の文字列を5文字に抑えるためには、3ビット削らなくてはならなかった。ということで、表現できる数値は、0~536870911(2^29-1)までとなります。
最初のゼロが0という文字列になるのが嫌な人は、0埋めするか(0→00000、1→00001にすること。ゼロパディングって言います)、0から使わないか(どうせDBから出てくるIDなんて1が起点だろ)、暗号化と復号のルーチンの要所に ^ (XOR)を仕込んどくといいよ。あと、これ暗号にはなりません。idを1増やして簡単に情報をたどられるのが嫌だ、程度の難読化ですよね。
一番怖いのはPerlのモジュールでこういうのを専門でやるモジュールが用意されていたりしそうだってことだ。
スポンサードリンク
トラックバック(0)
トラックバックURL: http://blog.dtpwiki.jp/MTOS/mt-tb.cgi/3229
コメントする