通常、進数変換は2進数を10進数、16進数を2進数にするなど数学的な計算に用いられる。それ以外であればbase64がメールで利用されている。これはマルチバイト文字をアルファベットなどに置き換えて送信し、受信側が再度組み立てるもの。なぜこの手順が必要かというと、メールでマルチバイト(日本語)文字などは直接送信できないため。
最近ではTwitterなど文字制限があるものに対して長いURLを投稿することが難しいため、URL短縮を目的とした利用や需要が高まっている。YouTubeは62進数を利用しているのではないかという記事が参考文献内にある。(10進数が0-9、16進数が0-9A-F、36進数が0-9A-Z、62進数が0-9A-Za-z、64進数が0-9A-Za-z+/、URLに64進数を使うと記号部をエンコードする必要がある、代わりに「-」「.」「!」を利用する方法もあるらしい)
一般的にはURL自体を圧縮するのではなく、データベース内のキー情報、例えばint型のカラムidが整数値であることを利用して、この数値を圧縮してURL転送するような仕掛けになっているようだ。
PHPで16新数を10進数に
HexDec("ff"); // -> 255
PHPで2-36進数を相互変換
string base_convert ( string $number , int $frombase , int $tobase )
PHPで2-36と62進数を変換
スポンサードリンク
echo $res = BaseConvert::convert("99999999999999",10,36); echo "\n"; // "zg3d62r5r" echo BaseConvert::convert($res,36,10); echo "\n"; // "99999999999999" echo $res = BaseConvert::convert("99999999999999",10,62); echo "\n"; // "SOYTZ0AR" echo BaseConvert::convert($res,62,10); echo "\n"; // "99999999999999"
※参考文献内にあるBaseConvert.inc.zipのコードを参照(以下一部抜粋)
function _from62($number, $frombase, $tobase) { static $CHARLEN = 62; static $FROM62TABLE = array( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 0, 0, 0, 0, 0, 0, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, 0, 0, 0 ); $num = 0; for ($i = 0; isset($number[$i]); $i++) { $num *= $CHARLEN; $num += $FROM62TABLE[ord($number[$i]) & 0x7f]; } $num = sprintf("%.0f", $num); if($tobase != 10) $num = base_convert($num, 10, $tobase); return $num; } function _to62($number, $frombase, $tobase) { static $CHARLIST = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; static $CHARLEN = 62; if($frombase != 10) $number = base_convert($number, $frombase, 10); $dst = ''; while ($number) { $dst = $CHARLIST[fmod($number, $CHARLEN)] . $dst; $number = floor($number / $CHARLEN); } return strval($dst); }
perlでの実装
※0-9a-zの36進数、14桁程度まで利用できる、参考文献より
use strict; my $base_str = "0123456789abcdefghijklmnopqrstuvwxyz"; my $base_36 = convert_36(1234567); print "$base_36\n"; my $base_10 = convert_10($base_36); print "$base_10\n"; sub convert_36 { my $number = shift; my @work; while ($number > 0) { unshift @work, substr($base_str, $number % 36, 1); $number = int($number / 36); } return join('', @work); } sub convert_10 { my @work = reverse split //, shift; my $number; foreach my $idx (0 .. $#work) { $number += index($base_str, $work[$idx]) * (36 ** $idx); } return $number; }
参考文献
- Memo/PHP – DEX Lab :
DEX Lab(移転しました) - 数字を文字列に変換し短縮化する – 質問・相談ならMSN相談箱 :
http://questionbox.jp.msn.com/qa4171320.html - PHPマニュアル:base_convert:数値の基数を任意に変換する :
http://php.plus-server.net/function.base-convert.html - Base64 – Wikipedia : http://ja.wikipedia.org/wiki/Base64 :
Base64 - Wikipedia
コメント