dec64(和名:でじこん)

数字列をURLで扱える形で変換する関数群です。
base64エンコードの数字入力限定版というとわかりやすいかも。

base64というと非ASCII文字列をASCII文字に変換する用途に使われますが、
このエンコードでは数字列を短縮化するのが目的です。

使用例

<?php
$dec64=new dec64();
$src="31415926535897";
$enc=$dec64->encode($src);
print $enc;
$dec=$dec64->decode($enc);
print $dec;

本体

<?php
class dec64 {
	function __construct() {
		// digit convert(0-9 to binary)
		$this->digicon= array(
			0=>'000',
			1=>'001',
			2=>'010',
			3=>'011',
			4=>'100',
			5=>'101',
			6=>'1100',
			7=>'1101',
			8=>'1110',
			9=>'1111'
		);
		
		// replace_list(6bit safecode)
		$replace_list=array();
		// 0-9 -> 0-9
		for ($i=0;$i<=9;$i++) {
			$replace_list[$i]=0x30+$i;
		}
		// 10-35 -> A-Z
		for ($i=10;$i<=35;$i++) {
			$replace_list[$i]=0x41+$i-10;
		}
		// 36-61 -> a-z
		for ($i=36;$i<=61;$i++) {
			$replace_list[$i]=0x61+$i-36;
		}
		// 62->'-' 63->'_'
		array_push($replace_list,0x2d,0x5f);
		$this->replace_list=$replace_list;
	}

	function encode($num) {
		$ebit='';
		for ($clm=0;$clm<strlen($num);$clm++) {
			$t=substr($num,$clm,1);
			$ebit .= $this->digicon[$t];
		}
		$mod=strlen($ebit)%6;
		switch ($mod) {
			case 0:
				$suffix='';
				break;
			case 1:
				$suffix='00011';
				break;
			case 2:
				$suffix='0001';
				break;
			case 3:
				$suffix='111';
				break;
			case 4:
				$suffix='00';
				break;
			case 5:
				$suffix='0';
				break;
		}
		return $this->bin64_encode($ebit . $suffix);
	}

	function bin64_encode($bin) {
		$rz='';
		
		for($cur_s=0;$cur_s<strlen($bin);$cur_s+=6) {
			$src=substr($bin,$cur_s,6);
			$gen=bindec($src);
			$dst=chr($this->replace_list[$gen]);
			$rz .= $dst;
		}
		return $rz;
	}

	function decode($str) {
		$exted=$this->bin64_decode($str);

		$sizesrc=strlen($exted);
		$clm=0;
		$ddig='';
		while ($sizesrc > $clm) {
			$remain=$sizesrc-$clm;
			$bef=substr($exted,$clm,2);
			if ($remain < 3) {
				break;
			}
			if ($bef == '11') {
				if ($remain==3) {
					break;
				}
				$enable_digits=4;
			} else {
				if ( (($remain==4) or ($remain==5)) and (substr($exted,-1,1) == '1') ) {
					break;
				}
				$enable_digits=3;
			}
			$unit=substr($exted,$clm,$enable_digits);
			$clm+=$enable_digits;
			$ddig .= array_search($unit,$this->digicon);
		}
		return $ddig;
	}

	function bin64_decode($str) {
		$rz='';
		
		for($cur_s=0;$cur_s<strlen($str);$cur_s++) {
			$src=substr($str,$cur_s,1);
			$gen=array_search(ord($src),$this->replace_list);
			$dst=sprintf("%06s",decbin($gen));
			$rz .= $dst;
		}
		return $rz;
	}
}
?>