从网上看了一些资料,为了方便自己理解,于是把它的编码原理,自己放在excel表格中清晰列出来,方便以后查阅。做的图如下:
ascii编码表
这个表很大,截图不出来。网上有。0-255的整数表示256个字符,即2的8次方=256。2的7次方是128。
参考:http://1024tools.com/ascii,图很清晰。
思考:base64编码算法,要求先去ascci表中对应字符的整数值。而ascci编码不支持中文的。从这个角度来看,base64_encode编码其实不支持中文编码的。具体中文编码后是什么情况,有待做一下试验后补充。
base64编码对应表
在程序中,用一个数组表示就是这样:
$base64_char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
比如整数24,那么就对应数组第25个元素:Y。
网上用的移位法,使用>>和<<,没有看明白怎么回事。根据编码的思路,拙劣地用php模拟实现了一个,对比一下与php内置的base64_encode()编码结果是不是一样
$string = 'abcde'; echo 'origin php 64 encode:'; var_dump(base64_encode($string)); function my_base64_encode($string = "") { $string_length = strlen($string); //看余数 $mod = $string_length % 3; //echo 'mod:<br />'; //var_dump($mod); $add_bin_value = ''; switch ($mod) { case 1: $add_bin_value = "0000000000000000"; break; case 2: $add_bin_value = "00000000"; break; } $group_count = ceil($string_length / 3); //得到多少组 //echo 'group <br />'; //var_dump($group_count); $string_arr = str_split($string, 1); $all_bin_value = ''; foreach ($string_arr as $key => $value) { $ascii_int = ord($value); //得到这个字符在ascii表中的对应的10进制整数 //然后把这个10进制整数,转换为二进制 //echo '$ascii_int:' . $ascii_int . "<br />"; $bin_value = decbin($ascii_int); //由于ascii的范围是0-255,如果是84,54这样比较小的值,这个函数会得到是一个1-7位的二进制。为了做到8位。于是增加判断一下,最高位要加0填充 $str_len = strlen($bin_value); if ($str_len < 8) { $add_zero_count = 8 - $str_len; //要增加这么多个0在前面,以便补充8位 for ($i = 0; $i < $add_zero_count; $i++) { $bin_value = '0' . $bin_value; } } //echo '$bin_value:' . $bin_value . "<br />"; $all_bin_value.= $bin_value; } $all_bin_value = $all_bin_value . $add_bin_value; //var_dump($all_bin_value); $bin_group_list = str_split($all_bin_value, 6); //每6个二进制一组,进行分组 //分组结果: //var_dump($bin_group_list); $base64_char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; $base64_char_arr = str_split($base64_char, 1); //var_dump($base64_char_arr); $dec_int = 0; $base64_encode_result = ''; foreach ($bin_group_list as $key => $value) { if ($value == '000000') { $base64_encode_result.='='; } else { $dec_int = bindec($value); //将二进制转换为10进制整数 //echo $dec_int . "<br />"; $base64_encode_result .= $base64_char_arr[$dec_int]; } } return $base64_encode_result; } $base64_encode_result = my_base64_encode($string); echo 'encode result:'; var_dump($base64_encode_result);
思考:
1、为什么要按照6位二进制一组进行分,而不是4位,7位等方式呢?
因为要考虑到只有64个字符供选择,十进制只能从0到63。最大值63。使用6位,2的6次方,值是64。
于是使用6位二进制的话,就能刚好对应出来。如果使用7位二进制。那么最大值是2的7次方,最大值是128。
假设计算得到的是数字是112,那么base64编码表中如何去对应呢?
2、为什么要每三个字符为一组呢?不是2个,也不是4个字符一组。是什么考虑?
不太清楚。尝试去分析一下,3个字符,,刚好是3*8=24位二进制。
24个字符要分成6个二进制一组。就是4个组。
2个字符呢,2*8=16 16/6也无法整除
如果是4个字符一组,4*8=32个字符。32/6 无法整除。
5个字符:5*8=40 40/6也无法整除。
6个字符一组,6*8=48 48/6=8 刚好可以整除。怎么没用这个方式呢?
应该是取小的原则。2个字符不可以,3个字符刚好可以。宁愿取小的。
待完善