时间:2021-07-01 10:21:17 帮助过:15人阅读
在一次接口对接中,要用到base64自定义编码表来进行编码和解码,从网上搜索了一下,讲原理的比较多也比较透彻,提供的编码的例子但是没有解码的,以下是自己实现的一个base64自定义字典解码的例子,比较粗糙,测试过集会应该没有问题,需要这块的可以拿去看一下,先将别人博客将原理的拿过来
Base64编码,是我们程序开发中经常使用到的编码方法。它是一种基于用64个可打印字符来表示二进制数据的表示方法。它通常用作存储、传输一些二进制数据编码方法!也是MIME(多用途互联网邮件扩展,主要用作电子邮件标准)中一种可打印字符表示二进制数据的常见编码方法!它其实只是定义用可打印字符传输内容一种方法,并不会产生新的字符集!有时候,我们学习转换的思路后,我们其实也可以结合自己的实际需要,构造一些自己接口定义编码方式。好了,我们一起看看,它的转换思路吧!
Base64实现转换原理
它是用64个可打印字符表示二进制所有数据方法。由于2的6次方等于64,所以可以用每6个位元为一个单元,对应某个可打印字符。我们知道三个字节有24个位元,就可以刚好对应于4个Base64单元,即3个字节需要用4个Base64的可打印字符来表示。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9 ,这样共有62个字符,此外两个可打印符号在不同的系统中一般有所不同。但是,我们经常所说的Base64另外2个字符是:“+/”。这64个字符,所对应表如下。
编号 | 字符 | 编号 | 字符 | 编号 | 字符 | 编号 | 字符 | |||
---|---|---|---|---|---|---|---|---|---|---|
0 | A | 16 | Q | 32 | g | 48 | w | |||
1 | B | 17 | R | 33 | h | 49 | x | |||
2 | C | 18 | S | 34 | i | 50 | y | |||
3 | D | 19 | T | 35 | j | 51 | z | |||
4 | E | 20 | U | 36 | k | 52 | 0 | |||
5 | F | 21 | V | 37 | l | 53 | 1 | |||
6 | G | 22 | W | 38 | m | 54 | 2 | |||
7 | H | 23 | X | 39 | n | 55 | 3 | |||
8 | I | 24 | Y | 40 | o | 56 | 4 | |||
9 | J | 25 | Z | 41 | p | 57 | 5 | |||
10 | K | 26 | a | 42 | q | 58 | 6 | |||
11 | L | 27 | b | 43 | r | 59 | 7 | |||
12 | M | 28 | c | 44 | s | 60 | 8 | |||
13 | N | 29 | d | 45 | t | 61 | 9 | |||
14 | O | 30 | e | 46 | u | 62 | + | |||
15 | P | 31 | f | 47 | v | 63 | / |
转换的时候,将三个byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。数据不足3byte的话,于缓冲区中剩下的bit用0补足。然后,每次取出6个bit,按照其值选择
中的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。
编码后的数据比原始数据略长,为原来的4/3。无论什么样的字符都会全部被编码,因此不像Quoted-printable 编码,还保留部分可打印字符。所以,它的可读性不如Quoted-printable编码!
文本 | M | a | n | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ASCII编码 | 77 | 97 | 110 | |||||||||||||||||||||
二进制位 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 |
索引 | 19 | 22 | 5 | 46 | ||||||||||||||||||||
Base64编码 | T | W | F | u |
M的Ascii码是77,前六位对应值为19,对应base64字符是T,如此类推。其它字符编码就可以自动转换得到!我们看看另外不是刚好是3个字节的情况!
文本(1 Byte) | A | |||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
二进制位 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | ||||||||||||||||
二进制位(补0) | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | ||||||||||||
Base64编码 | Q | Q | = | = | ||||||||||||||||||||
文本(2 Byte) | B | C | ||||||||||||||||||||||
二进制位 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | x | x | x | x | x | x | ||
二进制位(补0) | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | x | x | x | x | x | x |
Base64编码 | Q | k | M | = |
这个讲的很透彻,原文地址:http://www.cnblogs.com/chengmo/archive/2014/05/18/3735917.html
class base64{
public $base64_config = ['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','_','-'];
public function getBytes($string) {
$data = iconv("UTF-8","GBK",$string);
return unpack("C*",$data);
}
public function array_index($t){
return array_search($t, $this->base64_config);
}
public function decode($str){
$str = str_replace("!","",$str);
$slen = strlen($str);
$mod = $slen%4;
$num = floor($slen/4);
$desc = [];
for($i=0;$i<$num;$i++){
$arr = array_map("base64::array_index",str_split(substr($str,$i*4,4)));
$desc_0 = ($arr[0]<<2)|(($arr[1]&48)>>4);
$desc_1 = (($arr[1]&15)<<4)|(($arr[2]&60)>>2);
$desc_2 = (($arr[2]&3)<<6)|$arr[3];
$desc = array_merge($desc,[$desc_0,$desc_1,$desc_2]);
}
if($mod == 0) return implode('', array_map("chr",$desc));
$arr = array_map("base64::array_index", str_split(substr($str,$num*4,4)));
if(count($arr) == 1) {
$desc_0 = $arr[0]<<2;
if($desc_0 != 0) $desc = array_merge($desc,[$desc_0]);
}else if(count($arr) == 2) {
$desc_0 = ($arr[0]<<2)|(($arr[1]&48)>>4);
$desc = array_merge($desc,[$desc_0]);
}else if(count($arr) == 3) {
$desc_0 = ($arr[0]<<2)|(($arr[1]&48)>>4);
$desc_1 = ($arr[1]<<4)|(($arr[2]&60)>>2);
$desc = array_merge($desc,[$desc_0,$desc_1]);
}
return implode('', array_map("chr",$desc));
}
public function encode($str){
$byte_arr = $this->getBytes($str);
$slen=count($byte_arr);
$smod = ($slen%3);
$snum = floor($slen/3);
$desc = array();
for($i=1;$i<=$snum;$i++){
$index_num = ($i-1)*3;
$_dec0= $byte_arr[$index_num+1]>>2;
$_dec1= (($byte_arr[$index_num+1]&3)<<4)|($byte_arr[$index_num+2]>>4);
$_dec2= (($byte_arr[$index_num+2]&0xF)<<2)|($byte_arr[$index_num+3]>>6);
$_dec3= $byte_arr[$index_num+3]&63;
$desc = array_merge($desc,array($this->base64_config[$_dec0],$this->base64_config[$_dec1],$this->base64_config[$_dec2],$this->base64_config[$_dec3]));
}
if($smod==0) return implode('',$desc);
$n = ($snum*3)+1;
$_dec0= $byte_arr[$n]>>2;
///只有一个字节
if(!isset($byte_arr[$n+1])){
$_dec1= (($byte_arr[$n]&3)<<4);
$_dec2=$_dec3="!";
}else{
///2个字节
$_dec1= (($byte_arr[$n]&3)<<4)|($byte_arr[$n+1]>>4);
$_dec2= $this->base64_config[($byte_arr[$n+1]&0xF)<<2];
$_dec3="!";
}
$desc = array_merge($desc,array($this->base64_config[$_dec0],$this->base64_config[$_dec1],$_dec2,$_dec3));
return implode('',$desc);
}
}
$base64 = new base64();
//echo array_search("E",$base64->base64_config);
//exit;
$tt = $base64->encode("中文那在场也不怕asdasdas23232323,。、");
echo $tt."
";
$ttt = $base64->decode($tt);
echo $ttt."
";
http://www.bkjia.com/PHPjc/1084384.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/1084384.htmlTechArticlebase64自定义编码表 php版本, 在一次接口对接中,要用到base64自定义编码表来进行编码和解码,从网上搜索了一下,讲原理的比较多也比较...