Base64编码原理及应用

最近在做一个H5上传图片并压缩的项目,其过程主要是先将图片上传通过readAsDataURL获取上传图片base64编码,然后根据高宽比将图片画到canvas上实现压缩,在通过toDataURL获取压缩后的图片。点击可查看demo在该过程中用到base64编码,于是就想弄清楚base64编码原理,才有了这篇博客。

Base64编码的来历

为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送。这样用途就受到了很大的限制,比如图片二进制流的每个字节不可能全部是可见字符,所以就传送不了。最好的方法就是在不改变传统协议的情况下,做一种扩展方案来支持二进制文件的传送。把不可打印的字符也能用可打印字符来表示,问题就解决了。Base64编码应运而生,Base64编码就是一种基于64个可打印字符来表示二进制数据的表示方法。

Base64编码过程

  1. 将每三个字节作为一组,一共是24个二进制位。
  2. 将这24个二进制位分为四组,每个组有6个二进制位。
  3. 在每组前面加两个00,扩展成32个二进制位,即四个字节。
  4. 根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值。

Base64编码表

key char key char key char key char
0 A 17 R 34 i 51 z
1  B 18  S  35  j  52  0
2  C 19  T  36  k  53  1
3  D 20  U  37  l  54  2
4  E 21  V  38  m  55  3
5  F 22  W  39  n  56  4
6  G 23  X  40  o  57  5
7  H 24  Y  41  p  58  6
8  I 25  Z  42  q  59  7
9  J 26  a  43  r  60  8
10  K 27  b  44  s  61  9
11  L 28  c  45  t  62  +
12  M 29  d  46  u  63  /
13  N 30  e  47  v
14  O 31  f  48  w
15  P 32  g  49  x
16  Q 33  h  50  y

字符长度为能被3整除时,比如Man

            M           a           n
ASCII:      77          97          110
8bit字节:    01001101    01100001    01101110
6bit字节:      010011      010110      000101      101110
十进制:      19          22          5            46
对应编码:     T           W           F            u
  1. "M"、"a"、"n"的ASCII值分别是77、97、110,对应的二进制值是01001101、01100001、01101110,将它们连成一个24位的二进制字符串010011010110000101101110。
  2. 将这个24位的二进制字符串分成4组,每组6个二进制位:010011、010110、000101、101110。
  3. 在每组前面加两个00,扩展成32个二进制位,即四个字节:00010011、00010110、00000101、00101110。它们的十进制值分别是19、22、5、46。
  4. 根据上表,得到每个值对应Base64编码,即T、W、F、u。

字符串长度不能被3整除时,比如Lucy:

            L           u           c           y
ASCII:      76          117         99          121
8bit字节:    01001100    01110101    01100011    01111001      00000000    00000000
6bit字节:      010011      000111      010101      100011        011110      010000      000000  000000
十进制:      19          7           21          35            30          16             (补0) (补0)
对应编码:     T           H           V           j             e           Q            =       =

如果要编码的字节数不能被3整除,最后会多出1个或2个字节,那么可以使用下面的方法进行处理:
先使用0字节值在末尾补足,使其能够被3整除,然后再进行Base64的编码。在编码后的Base64文本后加上一个或两个=号,代表补足的字节数。也就是说,当最后剩余一个八位字节(1个byte)时,最后一个6位的Base64字节块有四位是0值,最后附加上两个等号;如果最后剩余两个八位字节(2个byte)时,最后一个6位的base字节块有两位是0值,最后附加一个等号。

因为,Base64将三个字节转化成四个字节,因此Base64编码后的文本,会比原文本大出三分之一左右。

注意
Base64编码主要用在传输、存储、表示二进制领域,不能算得上加密,只是无法直接看到明文,不建议用base64编码用于加密。
中文有多种编码(比如:utf-8、gb2312、gbk等),不同编码对应Base64编码结果都不一样。

base64实现

在PHP中,有一对专门的函数用于Base64转换:base64_encode()用于编码、base64_decode()用于解码。
在Javascript中可使用window.btoa()用于编码,window.atob()用于解码。 兼容性可点击查看IE10及以上全部兼容
对于IE10以下可采用以下兼容方法

/**
 * base64 encoding & decoding
 * for fixing browsers which don't support Base64 | btoa |atob
 */

(function (win, undefined) {

    var Base64 = function () {
        var base64hash = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

        // btoa method
        function _btoa(s) {
            if (/([^\u0000-\u00ff])/.test(s)) {  // 排除中文
                throw new Error('INVALID_CHARACTER_ERR');
            }
            var i = 0,
                prev,
                ascii,
                mod,
                result = [];

            while (i < s.length) {
                ascii = s.charCodeAt(i);
                mod = i % 3;

                switch (mod) {
                    // 第一个6位只需要让8位二进制右移两位
                    case 0:
                        result.push(base64hash.charAt(ascii >> 2));
                        break;
                    //第二个6位 = 第一个8位的后两位 + 第二个8位的前4位
                    case 1:
                        result.push(base64hash.charAt((prev & 3) << 4 | (ascii >> 4)));
                        break;
                    //第三个6位 = 第二个8位的后4位 + 第三个8位的前2位
                    //第4个6位 = 第三个8位的后6位
                    case 2:
                        result.push(base64hash.charAt((prev & 0x0f) << 2 | (ascii >> 6)));
                        result.push(base64hash.charAt(ascii & 0x3f));
                        break;
                }

                prev = ascii;
                i++;
            }

            // 循环结束后看mod, 为0 证明需补3个6位,第一个为最后一个8位的最后两位后面补4个0。另外两个6位对应的是异常的“=”;
            // mod为1,证明还需补两个6位,一个是最后一个8位的后4位补两个0,另一个对应异常的“=”
            if (mod == 0) {
                result.push(base64hash.charAt((prev & 3) << 4));
                result.push('==');
            } else if (mod == 1) {
                result.push(base64hash.charAt((prev & 0x0f) << 2));
                result.push('=');
            }

            return result.join('');
        }

        // atob method
        // 逆转encode的思路即可
        function _atob(s) {
            s = s.replace(/\s|=/g, '');
            var cur,
                prev,
                mod,
                i = 0,
                result = [];

            while (i < s.length) {
                cur = base64hash.indexOf(s.charAt(i));
                mod = i % 4;

                switch (mod) {
                    case 0:
                        //TODO
                        break;
                    case 1:
                        result.push(String.fromCharCode(prev << 2 | cur >> 4));
                        break;
                    case 2:
                        result.push(String.fromCharCode((prev & 0x0f) << 4 | cur >> 2));
                        break;
                    case 3:
                        result.push(String.fromCharCode((prev & 3) << 6 | cur));
                        break;
                }

                prev = cur;
                i++;
            }

            return result.join('');
        }

        return {
            btoa: _btoa,
            atob: _atob,
            encode: _btoa,
            decode: _atob
        };
    }();

    if (!win.Base64) { win.Base64 = Base64 }
    if (!win.btoa) { win.btoa = Base64.btoa }
    if (!win.atob) { win.atob = Base64.atob }

})(window)

Base64实际运用

  1. 用base64引入图片,当图片大小较小时可直接将其用base64编码,这样可以减少请求,目前webpack中可使用url-loader处理图片
  2. 在邮件中使用base64编码
参考文章
  1. Base64
  2. Base64笔记
  3. 关于base64编码的原理及实现

原文地址:https://www.cnblogs.com/jesse131/p/11529958.html

时间: 2024-10-26 04:09:27

Base64编码原理及应用的相关文章

Atitit.Base64编码原理与实现设计

Atitit.Base64编码原理与实现设计 1. Base64编码1 1.1. 为什么要用自己的base64编码方案1 2. Base64编码由来1 3. Base64编码原理1 3.1. 具体来说,转换方式可以分为四步:2 3.2. 注意2 3.3. Padding3 4. URL安全的Base64编码3 1. Base64编码 1.1. 为什么要用自己的base64编码方案 防止apache codec  jdk的jar冲突. 2. Base64编码由来 Base64最早是用来解决电子邮件

Base64 编码原理

1.编码表 2.原理[汉字不能base64编码] base64 编码就是将字符以3个为一组,因为一个字符由8个位组成,3*8=24位,然后以顺序以6个位拿出,前面补2位,凑成8位--一个字节 原字节不能被3整除的,在后面补 由8个0,构成的单字节,一般补1个或是2个(0000 0000),这些后面补的字节不能用base64编码对应,应该是异常字符,用“=”号替换, 所以,base64编码一般最后会有1~2个“=”号 示例: base64编码前:Lucy L u c yASCII: 76 117

BASE64编码原理分析脚本实现及逆向案例

BASE64编码原理分析脚本实现及逆向案例 0x01 简单介绍 数据传送时并不支持所有的字符,很多时候只支持可见字符的传送.但是数据传送不可能只传送可见字符为解决这个问题就诞生了base64编码.base64编码将所有待编码字符转换成64个可见字符表中的字符. 0x02 编码原理 被Base64编码之后所得到的所有字符都是在以下这个表当中的. 上表中总共有64个字符,2^6=64所以只需要6个bit位就足够描述所有的表中字符了.计算机中1个字节8个bit,一个ASCII码占1个字节.因此多出来的

Base64编码原理分析

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,在了解Base64编码之前,先了解几个基本概念:位.字节. 位:"位(bit)"是计算机中最小的数据单位.每一位的状态只能是0或1: 字节:8个二进制位构成1个"字节(Byte)",字节是存储空间的基本计量单位.1个字节可以储存1个英文字母,2个字节可以存储1个汉字: Base64编码的作用 因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通

Base64编码原理

转自: http://blog.chacuo.net/719.html Base64编码,是我们程序开发中经常使用到的编码方法.它是一种基于用64个可打印字符来表示二进制数据的表示方法.它通常用作存储.传输一些二进制数据编码方法!也是MIME(多用途互联网邮件扩展,主要用作电子邮件标准)中一种可打印字符表示二进制数据的常见编码方法!它其实只是定义用可打印字符传输内容一种方法,并不会产生新的字符集!有时候,我们学习转换的思路后,我们其实也可以结合自己的实际需要,构造一些自己接口定义编码方式.好了,

Base64编码原理与应用

本文内容转自网络,如需详细内容,请参考相关网址. http://my.oschina.net/goal/blog/201032 代码参考:http://blog.csdn.net/prsniper/article/details/7097643 Base64,它用作把任意序列的8位字节描述为一种不易被人直接识别的形式,常用作开发中用于传递参数.浏览器的img标签通过base64字符串来渲染图片以及电子邮件的正文编码等等. 在计算机中显示的字符,比如英文字母.数字以及英文标点符号就是用一个字节来存

BASE64编码原理与Golang代码调用

一.概念简介 Base64是一种基于64个可打印字符来表示二进制数据的表示方法.由于2^6=64,所以每6个比特为一个单元,对应某个可打印字符.3个字节有24个比特,对应于4个Base64单元,即3个字节可由4个可打印字符来表示.它可用来作为电子邮件的传输编码.在Base64中的可打印字符包括字母A-Z.a-z.数字0-9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同. Base64常用于在通常处理文本数据的场合,表示.传输.存储一些二进制数据 二.代码调用 在Golang中提供了

一篇文章彻底弄懂Base64编码原理

在互联网中的每一刻,你可能都在享受着Base64带来的便捷,但对于Base64的基础原理又了解多少?今天这篇博文带领大家了解一下Base64的底层实现. Base64的由来 目前Base64已经成为网络上常见的传输8Bit字节代码的编码方式之一.在做支付系统时,系统之间的报文交互都需要使用Base64对明文进行转码,然后再进行签名或加密,之后再进行(或再次Base64)传输.那么,Base64到底起到什么作用呢? 在参数传输的过程中经常遇到的一种情况:使用全英文的没问题,但一旦涉及到中文就会出现

知识扩展——(转)一篇文章彻底弄懂Base64编码原理

在互联网中的每一刻,你可能都在享受着Base64带来的便捷,但对于Base64的基础原理又了解多少?今天这篇博文带领大家了解一下Base64的底层实现. 一.Base64的由来 目前Base64已经成为网络上常见的传输8Bit字节代码的编码方式之一.在做支付系统时,系统之间的报文交互都需要使用Base64对明文进行转码,然后再进行签名或加密,之后再进行(或再次Base64)传输.那么,Base64到底起到什么作用呢? 在参数传输的过程中经常遇到的一种情况:使用全英文的没问题,但一旦涉及到中文就会