Base64解密(base64_decode)原理及如何使用 PHP 实现

接上一篇何谓 Base64 加密算法及原理,如何使用 PHP 实现一个 Base64_encode

现在我们来说一说如何解密使用 Base64 加密之后的内容,总的来说
Base64 解密就是加密的逆过程,加密的时候就是将每三个自己转为4个字符,
那么解密的时候就是将4个字符还原为三个字节,但需要注意的就是:
一、要和加密使用相同的字符表,2、要注意结束时填充的 “=”。
具体的讲一下过程:
每一次取四个字符,c1,c2,c3,c4,依次在字符表中查找他们的位置得到
i1,i2,i3,i4 
将 i1 的 6 位与 i2 高 2 位 组成字节 b1,
将 i2 的 低 4 位与 i3 的高 4 位 组成字节 b2,
将 i3 的 低 2 为与 i4 组成 字节 b3,
b1,b2,b3 就是我们的所需要的结果。

PHP 提供了一个 base64_decode,这里我们为了说明原理,就是用 PHP
在实现一个,代码为了具体表达算法过程就没有经过优化:
function zpz_find_char_index_in_array($aArray, $sChar){
	$i = count($aArray);
	while($i-- > 0){
		if($sChar === $aArray[$i]){
			return $i;
		}
	}
	//正确的 base64加密不会出现这种情况
	return false;
}

function zpz_base64_decode($sContent){
	$aTable = array(
		'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
		'I','J', 'K', 'L', 'M', 'N', 'O', 'P',
		'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
		'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
		'g', 'h', 'i','j', 'k', 'l', 'm', 'n',
		'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
		'w', 'x', 'y', 'z', '0', '1', '2', '3',
		'4', '5', '6', '7', '8', '9', '+', '/'
	);
	$iLength = strlen($sContent);
	$iLen = $iLength - 4;
	$i = 0;
	$aResult = array();

	//一个合法对 Base64 加密串的长度应该是 4 的倍数
	while($i < $iLen){
		$iCode1 = zpz_find_char_index_in_array($aTable, $sContent[$i++]);
		$iCode2 = zpz_find_char_index_in_array($aTable, $sContent[$i++]);
		$iCode3 = zpz_find_char_index_in_array($aTable, $sContent[$i++]);
		$iCode4 = zpz_find_char_index_in_array($aTable, $sContent[$i++]);

		$sChar1 = chr((($iCode1 & 63) << 2) | (($iCode2 & 48) >> 4));
		$sChar2 = chr((($iCode2 & 15) << 4) | ($iCode3 & 60) >> 2);
		$sChar3 = chr((($iCode3 & 3) << 6) | ($iCode4 & 63));
		array_push($aResult, $sChar1, $sChar2, $sChar3);
	}

	$iCode1 = zpz_find_char_index_in_array($aTable, $sContent[$i++]);
	$iCode2 = zpz_find_char_index_in_array($aTable, $sContent[$i++]);
	if('=' !== $sContent[$i]){
		$iCode3 = zpz_find_char_index_in_array($aTable, $sContent[$i++]);
		if('=' !== $sContent[$i]){
			$iCode4 = zpz_find_char_index_in_array($aTable, $sContent[$i]);

			$sChar1 = chr((($iCode1 & 63) << 2) | (($iCode2 & 48) >> 4));
			$sChar2 = chr((($iCode2 & 15) << 4) | ($iCode3 & 60) >> 2);
			$sChar3 = chr((($iCode3 & 3) << 6) | ($iCode4 & 63));

			array_push($aResult, $sChar1, $sChar2, $sChar3);
		}
		else{
			$sChar1 = chr((($iCode1 & 63) << 2) | (($iCode2 & 48) >> 4));
			$sChar2 = chr((($iCode2 & 15) << 4) | ($iCode3 & 60) >> 2);

			array_push($aResult, $sChar1, $sChar2);

		}
	}
	else{
		$sChar1 = chr((($iCode1 & 63) << 2) | (($iCode2 & 48) >> 4));
		array_push($aResult, $sChar1);
	}

	return join('', $aResult);
}

One Trackback

  1. […] 薹翮 我悄悄地离开,在昨天;今天我又静静地到来 SEO 查询工具   « 如何使用 mpm-itk 为 Apache 的每一个虚拟主机绑定一个用户 Base64解密(base64_decode)原理及如何使用 PHP 实现 » […]

Post a Comment

Your email is never shared. Required fields are marked *

*
*