ホームページ >バックエンド開発 >PHPチュートリアル >Base64エンコード原理の分析とPHP実装

Base64エンコード原理の分析とPHP実装

WBOY
WBOYオリジナル
2016-06-20 12:44:48992ブラウズ

Base64 は、64 個の印刷可能な文字に基づくバイナリ データの表現方法です。 2 の 6 乗は 64 に等しいため、6 ごとが単位となり、特定の印刷可能な文字に対応します。

3 ビットには 24 ビットがあり、4 つの Base64 ユニットに対応します。つまり、3 バイトを 4 つの印刷可能文字で表す必要があります。電子メールの転送エンコードとして使用できます。

Base64 の印刷可能な文字には、文字 A ~ Z、a ~ z、数字 0 ~ 9 が含まれるため、合計 62 文字になります。他の 2 つの印刷可能な記号はシステムによって異なります。

たとえば、mime (多目的メール拡張機能) では、Base64 で使用される 64 個の印刷可能な文字

A-Za-z: 大文字と小文字がそれぞれ 26 文字

0- 9: 数字を 10 個追加します

+: プラス記号

/: スラッシュ

合計 64 文字、等号「=」は接尾語として使用されます

対応する変換関係は

0-63: A-Za-z0-9+/


変換時、3 バイトのデータが24 ビット バッファに次々と入力され、最初に来たバイトが上位ビットを占めます。データが 3 バイト未満の場合、バッファ内の残りのビットは 0 で埋められます。次に、毎回 6 ビット (26=64 であるため) を取り出し、値に従って ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ の文字をエンコードされた出力として選択します。すべての入力データが変換されるまで続行します。

元のデータ長が 3 の整数倍ではない場合、入力データが最後に 1 つ残っている場合は、エンコード結果の後に「=」を 2 つ追加します。 、エンコード結果「=」の後に 1 を追加します。データが残っていない場合は、データ復元の正確性を確保するため、何も追加しません。

分析例:

エンコーディング: "Lailaiji"

ASCII テーブルを検索して対応する関係を見つけます

L:0x4c | a:0x61 | i:0x69 | l:0x6C | j:0x6A

つまりバイナリに変換されます: 0100 1100 , 0110 0001 , 0110 1001 , 0110 1001 , 0110 101 0 、0110 1001

th ステップ 1: まず 3 バイトのデータを取得します: 0100 1100、0110 0001、0110 1001、次にこれらの 3 バイトから 6 ビット (010011) を取り出し、最上位ビットに 2 ビット 00 を追加して 1 バイトにします、つまり 0001 0011、残りの 18 ビットもこのように循環し、最終的にこれら 3 バイトは 4 バイトに拡張されます: 0001 0011, 0000 0110, 0000 0101, 0010 1001

2 番目のステップ、残りからバイト シーケンスの最初のステップを繰り返し、3 バイト未満の場合は 3 番目のステップに進みます

この時点で、残りのバイトは 0110 1010、0110 1001 で、3 バイト未満です。下位ビットから 0 まで加算する必要があり、0110 1010、0110 1001、0000 0000 になります。最初の手順を繰り返して、0001 1010、0010 0110、0010 0100、0000 0000、

後続の演算の後、設定されたビット シーケンスを取得します:

0011, 0000 0110, 0000 0101, 0010 1001

0001 1011, 0000 0110, 0000 0101, 0010

0001 1010,0010 0110, 0010 0100, 0000 0000

10 進数に変換: 19, 6, 5, 41, 27, 6, 5, 41, 26, 38, 36, 0

対応する文字: T、G、F、p、b、G、F、p、a、m、k、A

特に注意が必要なのは、最後のバイトです。 0000 0000 は 0x00 で、テーブルを参照すると A です。最後の 8 ビットは補足的なため、A

ではなく = 記号に変換する必要があります。 したがって、最終結果は次のようになります: TGFpbGFpamk =

PHP 実装:

<?php$input = '赖来基';$obj = new MyBase64();$output = $obj->encode($input);echo "Encode:",$output.PHP_EOL;$output = $obj->decode($output);echo "Decode:",$output.PHP_EOL;class MyBase64{	private $_table = array();	private $_revtable = array();	public function __construct(){		$this->_initTable();	}	public function decode($string)	{		$orign_len = strlen($string);		$j = 0;		$ret = null;		for($i=0; $i<$orign_len; $i+=4)		{			$chr1 = $this->getRevChr($string[$i]);			$chr2 = $this->getRevChr($string[$i+1]);			$chr3 = $this->getRevChr($string[$i+2]);			$chr4 = $this->getRevChr($string[$i+3]);			$_chr1 = $chr1<<2 | ($chr2&0x3F) >>4;			$_chr2 = ($chr2&0x0F)<<4 | ($chr3&0xFC) >>2;			$_chr3 = ($chr3&0x03)<<6 | $chr4;			$ret .= chr($_chr1);			$ret .= chr($_chr2);			$ret .= chr($_chr3);		}		$ret = rtrim($ret);		return $ret;	}	private function getRevChr($chr)	{		if(isset($this->_revtable[$chr]))		{			return $this->_revtable[$chr];		}else{			return 0;		}	}	public function _decode($string)	{		$orign_len = strlen($string);		$de = null;		$kv = array_flip($this->_table);		$b  = null;		for($i = 0 ;$i < $orign_len;$i++)		{			$chr = $string[$i];			if($chr != '='){				$c = $kv[$chr];			}else{				$c = chr(0);			}			printf("%x",$c);			$b[] = pack('C',$c);			echo PHP_EOL;		}		for($i = 0 ;$i < count($b);$i+=3){			$ch1 = ($b[$i]<<2) | ($b[$i+1]>>4);			$ch2 = ($b[$i+1]<<4) | ($b[$i+2]>>2);			$ch3 = ($b[$i+2]<<6) | ($b[$i+3]);			printf('%08b,%08b,%08b',$ch1,$ch2,$ch3);			echo PHP_EOL;			printf('%08b,%08b',($b[$i]<<2) , ($b[$i+1]>>4));			echo PHP_EOL;		}	}	public function encode($string)	{		$orign_len = strlen($string);		$len       = intval(ceil($orign_len/3)*3);		$bin       = pack('a'.$len,$string);		$gen       = null;		for($i=0; $i<$len; $i+=3)		{			$ch1 = ord($bin[$i]) >> 2;			$ch2 = ((ord($bin[$i]) & 0x03) << 4) | (ord($bin[$i+1]) >> 4);			$ch3 = ((ord($bin[$i+1]) & 0x0F) << 2) | ((ord($bin[$i+2]) & 0xC0) >> 6);			$ch4 = ord($bin[$i+2]) & 0x3F;			$gen.= $this->_table[$ch1];			$gen.= $this->_table[$ch2];			$gen.= $this->_table[$ch3];			$gen.= $this->_table[$ch4];		}		if($orign_len-$len){			$gen = substr($gen,0, -abs($orign_len-$len));			for($i=0;$i<$len-$orign_len;$i++)			{				$gen .= '=';			}					}		return $gen;	}	private function  _initTable()	{		$tbl = array();		for($i=ord('A');$i<=ord('Z');$i++)		{			$tbl[] = chr($i);		}		for($i=ord('a');$i<=ord('z');$i++)		{			$tbl[] = chr($i);		}		for($i=ord('0');$i<=ord('9');$i++)		{			$tbl[] = chr($i);		}		$tbl[]           = '+';		$tbl[]           = '/';		$reverse         = array_flip($tbl);		$this->_table    = $tbl;		$this->_revtable = $reverse;	}}


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。