Base64编码的原理是按bit将每6个bit转换成Base64编码表中的相应字符。下面是Base64的编码表:

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

在转换到最后一个字节时,可能出现如下两种情况:
    1.  最后只剩下2个bit。
    2.  最后只剩下4个bit。
    对于这两种情况,需要在后面被0,如下面的两个字节:

    11011001 11011101

在转换上面的字节时,最后会剩下4个bit。也就是1101,这时需要在后面补0,也就是变成了110100。如果后面补一对0,转换结果后面加一个“=”,如果补两对0,加两个“=”,也就是总共的bit数除3的余数为1,则加一个“=”,余数为2,加两个“=”。上面的两个字节是16个bit,除3的余数是1,因此,需要补一个“=”,也就是将这两个字节分成如下三组:

    110110  011101  110100 

其中110100后面两个0是补的,因此,查找上面的base64编码表可将这两个字节转换成如下的Base64编码:

    2d0=

下面我们来实现这个算法。算法的基本原理如下:

由于每次转换都需要6个bit,而这6个bit可能都来自一个字节,也可以来自前后相临的两个字节。定义两个变量:prevByteBitCount和nextByteBitCount,这两个变量分别表述从前一个和后一个节字取得的bit数。如果prevByteBitCount为0,表示6个bit全部来自下一个字节的高6位。如果nextByteBitCount = 0,表示6个bit全部来自前一个字节的低6位。最后通过适当的移位获得所需要的6个bit,再在上面的base64编码表中查找相应的字符。算法的实现代码如下:

    public static String encoder(byte[] bytes)
    {
        StringBuilder result = new StringBuilder();
        String base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        //  prevByteBitCount表示从前一个字节取得的bit数,nextByteBitCount表示从后一个字节取得的bit数
        int prevByteBitCount = 0, nextByteBitCount = 6;
        //  i表示当前的数组索引,n表示已经处理的位数
        int i = 0, n = 0;
        //  byteCount表示总的位数
        int byteCount = 8 * bytes.length;
        byte b = 0;
        while (true)
        {
            //  处理从前后两个字节取得位数的情况
            if (prevByteBitCount > 0 && nextByteBitCount > 0)
            {
                // 将前一个字节的低位向左移nextByteBitCount个bit,并使下一个字节的高位(nextByteBitCount指定的位数)右移到字节的最低位,
                // 然后将两个位移结果进行逻辑或,也就是将从前一个字节和后一个字节取得的相应的bit合并为一个字节的低位
                b = (byte) (((0xff & bytes[i]) << nextByteBitCount) | ((0xff & bytes[i + 1]) >> (8 - nextByteBitCount)));
                //  将逻辑或后的结果的最高两个bit置成0
                b = (byte) (b & 0x3f);
                prevByteBitCount = 8 - nextByteBitCount;
                nextByteBitCount = 6 - prevByteBitCount;
            }
            //  处理从后一个字节取得高6位的情况
            else if (prevByteBitCount == 0)
            {
                //  后一个字节的高6位右移动低6位
                b = (byte) ((0xff & bytes[i]) >> (8 - nextByteBitCount));
                //  处理后面的位时,就是从前一个字节取2个bit,从后一个字字取4个bit
                prevByteBitCount = 2;
                nextByteBitCount = 4;

}
            //  处理从前一个字节取得低6位的情况
            else if (nextByteBitCount == 0)
            {
                //  将前一个字节的最高两个bit置成0
                b = (byte) (0x3f & bytes[i]);
                //  处理后面的位时,从后一个字节取6个bit
                prevByteBitCount = 0;
                nextByteBitCount = 6;

}
            result.append(base64.charAt(b));
            n += 6;
            i = n / 8;
            int remainBitCount = byteCount - n;
            if (remainBitCount < 6)
            {
                //  将剩余的bit补0后,仍然需要在base64编码表中查找相应的字符,并添加到结果字符串的最后
                if (remainBitCount > 0)
                {
                    b = bytes[bytes.length - 1];
                    b = (byte) (0x3f & (b << (6 - remainBitCount)));
                    result.append(base64.charAt(b));
                }
                break;
            }
        }
        //  如果总bit数除3的余数为1,加一个“=”,为2,加两个“=”
        n = byteCount % 3;
        for (i = 0; i < n; i++)
            result.append("=");

return result.toString();
    }

最后可以使用下面的代码来验证encoder方法的正确性:

    String s = "中华人民共和国";
    byte[] bytes = s.getBytes("UTF-8");
    System.out.println(encoder(bytes));
    //  使用jdk提供的base64转换类对字节数组进行base64编码
    sun.misc.BASE64Encoder base64Encoder = new sun.misc.BASE64Encoder();
    System.out.println(base64Encoder.encode(bytes));

上面的代码的执行结果如下:

5Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9
5Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9
国内最棒的Google Android技术社区(eoeandroid),欢迎访问!

《银河系列原创教程》发布

《Java Web开发速学宝典》出版,欢迎定购

Base64编码原理与实现相关推荐

  1. base64编码_几分钟看懂Base64编码原理

    Base64简介 Base64是基于64个可打印字符(小写字母a-z,大写字母A-Z,数字0-9,符号"+","/" 再加上作为垫字的"=" ...

  2. Base64 编码原理及代码实现

    Base64 编码原理及代码实现 所谓 base64 编码就是从 ASCII 码表中选取64个可打印字符(A-Za-z0-9+/)作为基本字符集对其它字符进行编码转换.加上作为填充的 "=& ...

  3. 密码学-编码算法:Base64编码原理和使用

    1.Base64简介 Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法.Base64编码是从二进制到字符的过程,可用于在 ...

  4. 5分钟学会Base64编码原理

    Base64编码原理 一.前言        相信很多开发的小伙伴当听到 Base64的时候,都会误认为是它一种加密解密的算法.        其不然,Base64其实是一种编码格式,其作用:解决乱码 ...

  5. Base64编码原理与应用

    本文内容转自网络,如需详细内容,请参考相关网址. http://my.oschina.net/goal/blog/201032 代码参考:http://blog.csdn.net/prsniper/a ...

  6. 一文轻松明白 Base64 编码原理

    把图片丢进浏览器,打开sources能看到一长串字符串,这是图片的Base64编码.这一长串编码到底是怎么生成的呢? 我们接下来探索一下base64编码的原理 Base64 名称的由来 Base64编 ...

  7. C++安全方向(二):2.3 base64编码原理讲解

    我们目前的编码可以理解为base256 4位是0-16 6位是0-63,能表示我们的base64,所以base64我们是取6位表示一个字节.

  8. base64编码原理+源码

    看一下Base64的索引表,字符选用了"A-Z.a-z.0-9.+./" 64个可打印字符.数值代表字符的索引,这个是标准Base64协议规定的,不能更改.64个字符用6个bit位 ...

  9. Base64编码的原理与常用实现

    这篇主要是为了后面好介绍加密算法,做的铺垫. 这个是基础,什么是一个程序员的涵养,这些基础就是涵养. 平时可能用不到,但必须得会. 如果连这个原理都说不上来,就别玩王者荣耀绝地求生英雄联盟和平精英了, ...

最新文章

  1. LeetCode 1115. Print FooBar Alternately--多线程并发问题--Java解法--CyclicBarrier, synchronized, Semaphore 信号量
  2. [LeetCode]Contains Duplicate III
  3. python脚本调度程序_Windows 任务调度程序定时执行Python脚本
  4. 判断随机抽取代码_高中数学中离散型随机变量的分布列知道吗?均值与方差能干什么?...
  5. 《北妹》:中国七零后作家的一次火山喷发(答记者问)
  6. 一款jQuery立体感动态下拉导航菜单特效
  7. jquery实现饼图统计图表
  8. python struct pack解析_Python struct 详解
  9. Chrome插件管理、在线离线安装方式、部分插件介绍
  10. 金蝶K3系统BOM数据批量审核/使用语句
  11. 使用第三方类库对html进行解析
  12. hp服务器怎么装win7系统,惠普280 Pro G4台式机intel 8代cpu安装win7步骤
  13. leetcode 1859 又是一道字符串分隔的题目
  14. python 实现usn读取记录
  15. 2.3 数据库-深入理解
  16. CSS控制按钮渐变过渡效果(鼠标移入移出)
  17. linux大于3T硬盘多个分区,Ubuntu挂载3T硬盘或大于2T磁盘的方法
  18. Python下载微信公众号文章和图片保存至本地
  19. 6G新天线技术白皮书(附下载)
  20. Unicode和UTF8的区别

热门文章

  1. 死机、蓝屏、系统运行过慢
  2. 《马哥教育协办GIAC、GOPS顶级技术峰会完美落幕》
  3. 云巴创始人张虎:一个优秀的软件工程师必然是全栈工程师
  4. 配置scp在Linux或Unix之间传输文件无需密码
  5. 数据库结构Sqlite与CoreData
  6. 一起谈.NET技术,也玩MVC3.0 Razor自定义视图引擎来修改默认的Views目录结构
  7. python前端HTML和CSS进阶
  8. PAT1123 Is It a Complete AVL Tree(AVL树完全二叉树)
  9. linux取随机数shell版本
  10. 1.mysql数据库安装不成功的解决方案