浅谈Base64编码

以前写过两篇博客(解决getImageData跨域问题用php把图片编码嵌入到html)来介绍Base64相关函数解决项目中的问题,今天主要来探究Base64是如何工作的,做到之所以然并知其所以然。

Base64包含A-Z、a-z、0-9、+、/、=65个字符,其中“=”来做结尾填充之用,不在索引表内。下表数值代表字符的索引,如同PHP的数组,数值为键,字符为值,一一对应。

这里写图片描述

因为去掉“=”后,Base64只有64个字符,那么可以用2^6表示,也就是说可以用6个bit的二进制表示;而标准的字符是8个bit,那么取二者的最小公倍数24,也就说3个标准字符可以用4个Base64字符来表示,由此也可以看出Base64编码后占用空间变大了。

以字符串“hello world”为例来说说Base64实现原理

  • 分组,每3个字符为一组。([hel]、[lo ]、[wor]、[ld])
  • 对照ASCII码表,分别获取字符串的ASCII编码。([104 101 108]、[108 111 32]、[119 111 114]、[108 100])
  • 依次把ASCII编码转成二进制。([01101000 01100101 01101100]、[01101100 01101111 00100000]、[01110111 01101111 01110010]、[01101100 01100100])
  • 把每组中8*N个bit改为6*N个bit,并且保证每组有24个bit,不足的在高位补0。([011010 000110 010101 101100]、[011011 000110 111100 100000]、[011101 110110 111101 110010]、[011011 000110 010000 000000])
  • 在每组6bit前面都填两个高位0,得到4个8bit的字节,转成10进制并对照Base64编码表 ,得到对应编码后的字符。(aGVsbG8gd29ybGQ=,其中最右侧的“=”号是最后一组6个0填充的换来的)
echo base64_encode('hello world'); // aGVsbG8gd29ybGQ=

上面举得例子中的字符串须在ASCII编码范围内,中文就不行。下面来说说在UTF-8编码内中文的的实现方法,中文在UTF-8编码中占三个字节,“永”字的对应的十进制为“ 230 176 184”,对应的十六进制为“e6 b0 b8”,换算成二进制“00110010 00110001 00110001”,然后套用上面的方法可以得出Base64编码“5rC4”

echo base64_encode('永'); // 5rC4

注:下面的为中文转十进制、十六进制方法,via 网络

$string = "永";
$length = strlen($string);
$result = array();

// 十进制
for($i=0;$i<$length;$i++){
    if(ord($string[$i])>127){
        $result[] = ord($string[$i]).' '.ord($string[++$i]).' '.ord($string[++$i]);
    }
}
print_r($result);
echo '<br>';

// 十六进制
$strings = array();
foreach($result as $v){
    $dec = explode(" ",$v);
    $strings[] = dechex($dec[0])." ".dechex($dec[1])." ".dechex($dec[2]);
}
print_r($strings);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值