BASE64编码
简介
Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,可用于在HTTP环境下传递较长的标识信息。Base64 算法最早应用于解决电子邮件传输的问题,在早期,由于“历史问题”,电子邮件只允许 ASCII 码字符,如果要传送一封带有非 ASCII 码字符的电子邮件,当它通过一些网关的时候就可能出现问题。这个网关很可能会对这个非 ASCII 码字符的二进制位做调整,即将这个非 ASCII 码的 8 位二进制码的最高位置为 0,此用户收到的邮件就会是一封纯粹的乱码邮件,基于这个原因产生了 Base64 算法。
在网络中,通过HTTP传输的文件还可以通过base64对数据进行编码进行传输。Base64编码的文件不仅仅是图片,也可以是字体文件。
Base64编码定义
Base64是一种基于64个字符的编码算法,以任意8位字节序列组合的描述形式,这种形式不易直接识别。经过Base64编码后的字符串的字符数是以4为单位的整数倍。
在线Base64工具
http://tool.chinaz.com/Tools/Base64.aspx
使用base64:URL的优缺点
优点:
- Data URL是在本地直接绘制图片,不是从服务器加载,所以节省了HTTP连接,起到加速网页的作用,减少了HTTP请求。
- 某些文件可以避免跨域的问题
- 没有图片更新要重新上传,还要清理缓存的问题。
缺点和不足:
- 浏览器支持
使用base64编码图片作为背景图片的这种技术IE6/IE7浏览器是不支持的(IE9浏览器IE7模式下支持)。对于目前PC页面,兼容性问题使没有文件上传以及无需更新缓存的优点不存在了。 - 增加了CSS文件的尺寸
base64编码图片本质上是将图片的二进制大小以一些字母的形式展示,例如一个1024字节的图片,base64编码后至少1024个字符,这个大小会被完全嵌入到CSS文件中(不过幸运的是也可以被gzip了,而图片文件被gzip效果不明显)。 - 编码成本
图片完成后还需要base64编码,目前估计手工完成的多,因此,增加了一定的工作量,虽然不多。 - 不会缓存
- html代码膨胀
使用base64编码替代图片的情况:
在web页面制作的时候,由于某些现实原因,我们可以会用到下面这一类图片:
1. 这类图片不能与其他图片以CSS Sprite的形式存在,只能独行。
2. 这类图片从诞生之日起,基本上很少被更新。
3. 这类图片的实际尺寸很小。
4. 这类图片在网站中大规模使用。
Base64编码表
这些字符和数值之间有一个对应表,整个的编码都是按照这个对应表来进行的。
码值 | 字符 | 码值 | 字符 | 码值 | 字符 | 码值 | 字符 |
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 | 0 | 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 | / |
Base64编码说明
Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节,则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='。
为了保证所输出的编码位可读字符,Base64制定了一个编码表,以便进行统一转换。编码表的大小为2^6=64,这也是Base64名称的由来。
base64
加密是不管原始数据如何编码的, 编码后的数据时ascii
字符, 一般默认结果中出现的字符有[0-9a-zA-z+/]
共64个字符, 所以叫base64
.
然而,我们知道1字节等于8位。当拿到一个字符串的时候,首先找到每个字符对应的ascII码,再将ascII码转换成8位二进制表示('A'=65=01000001)。然后将字符串转换成的二进制串再按照每6位为一组进行划分。这样用每6位二进制数对应的十进制数去上面的对照表中取出相应的字符。举个例子:对'PHP'进行base64编码。
Base64应用
将文件生成base64图片流代码片段
function base64_encode_image ($file_name='',$file_type='') { if (!empty($file_name)) { $img_binary = fread(fopen($file_name, "r"), filesize($file_name)); return 'data:image/' . $file_type . ';base64,' . base64_encode($img_binary); } }
下面是一段base64编码后的传输过来的文件在目录下生成文件(这段是我在项目中使用的)
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_img, $result)) { $type = $result[2]; if (in_array($type, array('pjpeg', 'jpeg', 'jpg', 'gif', 'bmp', 'png'))) { $file_name = $topic_id . date('YmdHis') . rand(999, 99999) . '.' . $type; $path = './images/tenement/' . $modul . '/'; //判断创建目录 if (!is_dir($path)) { $issuccess = mkdir(iconv("UTF-8", "GBK", $path), 0777, true); if (!$issuccess) { return AjaxResponse::fail('目录创建失败', true, $jsonp); } } $new_file = $path . $file_name; if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_img)))) { KyTopic::where('topic_id','=',$topic_id)->update([ 'topic_img'=>$file_name ]); return AjaxResponse::success($this->topic_img_path.$file_name); } else { return AjaxResponse::fail('图片保存失败', true, $jsonp); } } else { //文件类型错误 return AjaxResponse::fail('文件类型错误', true, $jsonp); } } else { return AjaxResponse::fail('错误数据', true, $jsonp); }
base64缺点:
base64编码的缺点在于其体积比原图片更大,因为Base64将三个字节转化成四个字节,因此编码后的文本,会比原文本大出三分之一左右,所以对于体积很大的文件来说,上传和解析的时间会明显增加。