一、Base64实现转换原理

  它是用64个可打印字符表示二进制所有数据方法。由于2的6次方等于64,所以可以用每6个位元(bit)为一个单元,对应某个可打印字符。我们知道三个字节(byte)有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 /

  

  仔细思考一下,你会很快发现,一个问题,就是每次转换的字节数不一定就是24的整数倍,会出现有多余不足六位的情况,在base64中处理的方法是加零凑够六位,但是这样一来在解码的时候就会出现多余的位  这该怎么办呢? base64想到了一个很好的解决办法。这个办法就是在 base64凑零的同时,还要满足凑出来的位数是8的倍数,不然就加一个或者两个特殊的六位  =  符号。为什么是一个或者两个=符号呢? 因为多个8位转为6位 只会出现 剩余 2位,4位的情况,剩余2位 只需要一个 表示六位的 =  便可变为8的整数;而剩余4位 需要两个表示6位的 = 便可以变成16 是8的整数。然后在解密的时候不解析 =即可。

之所以位的总数需要凑成8的倍数,是因为base64主要用于加密后的数据传送,而在传送机制中都认为传送的最小单位是按照字节算的,所以不能出现不是位总数不是8的倍数的情况,在接收到数据后,按顺序将6位的base64直接按照顺序解密成字节就完成解密了。

· 转换过程:

    ① 将三个byte(字节)的数据,先后放入一个24bit(位)的缓冲区中,先来的byte占高位。数据不足 3 byte的话,于缓冲区中剩下的bit用0补足。

    ② 然后,每次取出6个bit,按照其值选择 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ 中的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。

    ③    如果最后剩下两个输入数据,在编码结果后加1个“=”;

      如果最后剩下一个输入数据,编码结果后加2个“=”;

      如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。

   编码后的数据比原始数据略长,为原来的4/3。

文本 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  =

二、Base64转换代码实现

 public class Base64Util {
private static final char last2byte = (char) Integer.parseInt("00000011", 2);
private static final char last4byte = (char) Integer.parseInt("00001111", 2);
private static final char last6byte = (char) Integer.parseInt("00111111", 2);
private static final char lead6byte = (char) Integer.parseInt("11111100", 2);
private static final char lead4byte = (char) Integer.parseInt("11110000", 2);
private static final char lead2byte = (char) Integer.parseInt("11000000", 2);
private static final char[] encodeTable = new char[]
{
'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 Base64Util() {
} public static String encode(byte[] from) {
StringBuilder to = new StringBuilder((int) ((double) from.length * 1.34D) + 3);
int num = 0;
char currentByte = 0; int i;
for (i = 0; i < from.length; ++i) {
for (num %= 8; num < 8; num += 6) {
switch (num) {
case 0:
currentByte = (char) (from[i] & lead6byte);
currentByte = (char) (currentByte >>> 2);
case 1:
case 3:
case 5:
default:
break;
case 2:
currentByte = (char) (from[i] & last6byte);
break;
case 4:
currentByte = (char) (from[i] & last4byte);
currentByte = (char) (currentByte << 2);
if (i + 1 < from.length) {
currentByte = (char) (currentByte | (from[i + 1] & lead2byte) >>> 6);
}
break;
case 6:
currentByte = (char) (from[i] & last2byte);
currentByte = (char) (currentByte << 4);
if (i + 1 < from.length) {
currentByte = (char) (currentByte | (from[i + 1] & lead4byte) >>> 4);
}
} to.append(encodeTable[currentByte]);
}
} if (to.length() % 4 != 0) {
for (i = 4 - to.length() % 4; i > 0; --i) {
to.append("=");
}
} return to.toString();
}
}

Base64加密转换原理与代码实现的更多相关文章

  1. Base64加密解密原理以及代码实现(VC++)

    Base64加密解密原理以及代码实现 转自:http://blog.csdn.net/jacky_dai/article/details/4698461 1. Base64使用A--Z,a--z,0- ...

  2. Base64加密解密原理以及代码实现

    1. Base64使用A--Z,a--z,0--9,+,/ 这64个字符.    2. 编码原理:将3个字节转换成4个字节( (3 X 8) = 24 = (4 X 6) )先读入3个字节,每读一个字 ...

  3. Base64编码转换原理

    Base64编码,是我们程序开发中经常使用到的编码方法.它是一种基于用64个可打印字符来表示二进制数据的表示方法.它通常用作存储.传输一些二进制数据编码方法.它其实只是定义用可打印字符传输内容一种方法 ...

  4. base64加密和解码原理和代码

    Base64编码,是我们程序开发中经常使用到的编码方法.它是一种基于用64个可打印字符来表示二进制数据的表示方法.它通常用作存储.传输一些二进制数据编码方法!也是MIME(多用途互联网邮件扩展,主要用 ...

  5. Java 和JS Base64加密

    项目在登录.注册等场景实现时,经常会用到用户信息前端加密,然后项目后端二次解密,避免信息直接在浏览器上以明文显示. 本文主要介绍了base64加密的方式处理代码,不支持中文 源码如下: base64. ...

  6. Java Base64加密、解密原理Java代码

    Java Base64加密.解密原理Java代码 转自:http://blog.csdn.net/songylwq/article/details/7578905 Base64是什么: Base64是 ...

  7. Base64图片编码原理,base64图片工具介绍,图片在线转换Base64

    Base64图片编码原理,base64图片工具介绍,图片在线转换Base64 DataURI 允许在HTML文档中嵌入小文件,可以使用 img 标签或 CSS 嵌入转换后的 Base64 编码,减少  ...

  8. Java的Base64加密原理

    出自:   http://www.cnblogs.com/winner-0715/p/5920269.html http://www.cnblogs.com/koliop090/p/5203553.h ...

  9. 【代码笔记】iOS-3DES+Base64加密解密

    一,工程目录. 二,代码. RootViewController.m #import "RootViewController.h" #import "NSString+T ...

随机推荐

  1. Spring Boot - 配置介绍

    Spring Boot 针对常用的开发场景提供了一系列自动化配置来减少原本复杂而又几乎很少改动的模板配置内容,但是,我们还是需要了解如何在Spring Boot中修改这些自动化的配置,以应对一些特殊场 ...

  2. Syncthing – 数据同步利器---自己的网盘,详细安装配置指南,内网使用,发现服务器配置

    简介: 无论办公.文件共享.团队协作还是家庭照片.视频.音乐.高清电影的存储,我们常常都有文件同步和存储的需求.但随着国内各大网盘的花式阵亡或限速,早已没什么好选择了.好吧,我已经转战使用onedri ...

  3. instant client 的配置

    instant client 的配置 oracle server developer自带了客户端 解压目录:D:\Toolkit\instantclient_11_2 设置环境变量 Ø  在Path变 ...

  4. MySQL导出数据字典

    平时用mysql比较多,有时候需要详细的数据库设计表结构和数据字典,但又没有最新的文档,这个时候直接从数据导出是最新最全的.在MySQL数据库中利用information_schema库中的COLUM ...

  5. python常见循环练习

    第一题:求5的阶乘 # 方法1,递归 def jc(num): if num == 1: return 1 else: return num*jc(num-1) print(jc(5)) # 方法2, ...

  6. RF:操作笔记

    1.变量运算

  7. 62.纯 CSS 创作一只蒸锅(感觉不好看呀)

    原文地址:https://segmentfault.com/a/1190000015389338 HTML code: <!-- steamer: 蒸锅: lid: 盖子: pot: 锅 --& ...

  8. Python正则替换字符串函数re.sub用法示例(1)

    本文实例讲述了Python正则替换字符串函数re.sub用法.分享给大家供大家参考,具体如下: python re.sub属于python正则的标准库,主要是的功能是用正则匹配要替换的字符串然后把它替 ...

  9. 用java语言构建一个网络服务器,实现客户端和服务器之间通信,实现客户端拥有独立线程,互不干扰

    服务器: 1.与客户端的交流手段多是I/O流的方式 2.对接的方式是Socket套接字,套接字通过IP地址和端口号来建立连接 3.(曾经十分影响理解的点)服务器发出的输出流的所有信息都会成为客户端的输 ...

  10. MySQL InnoDB内存压力判断以及存在的疑问

    本文出处:http://www.cnblogs.com/wy123/p/7259866.html(保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错误 ...