一、什么是Base64编码

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一。Base64 主要不是加密,它主要的用途是把一些二进制数转成普通字符用于网络传输。 由于一些二进制字符在传输协议中属于控制字符,不能直接传送需要转换一下。Base64编码就是把二进制字节序列转化为ASCII字符序列。一般增加1/3长度,而且也是不可读的。 使用的字符包括大小写字母各26个,加上10个数字,和加号“+”,斜杠“/”,一共64个字符,等号“=”用来作为后缀用途。

二、Base64原理

[源数据]——>[获得源数据的二进制流]——>[每3个8位二进制转换为4个6位二进制]——>[每6位二进制转换为十进制]——>[对照表转换为Base64数据]

关键点:3个8位二进制转换4个6位二进制的方法 将输入的二进制数据流以每次读取6个bit的方式读取,不足6位的后补0,将每3个8位二进制转换为4个6位二进制,也就是说每3个8位字节将编码为4个6位字节(3×8 → 4×6);不满4个字节的以“=”填充。其实这4个六位字节仍然是8位,只不过高两位被设置为0。当一个字节只有6位有效时,它的取值空间为0 到 2的6次方减1 即63,也就是说被转换的Base64编码的每一个编码的取值空间为(0-63)。事实上,0-63之间的ASCII码有许多不可见字符,所以应该再做一个映射,映射表(码表)为:

码字 个数 ASCII码 对应的6bit值
0 - 9 10个 48 - 57 52 - 61
A - Z 26个 65 - 90 0 - 25
a - z 26个 96 - 122 26 - 51
+ 1个 43 62
/ 1个 47 63

三、Base64应用

1.mail

由于rfc821有以下两条限制:

1)邮件的内容必须全部为7-比特的美国ascii码。

2)每一行的长度不能超过1000的字符 当邮件中有其他的非ASCII字符或二进制数据时,就需要做转换。这个就叫做Content-Transfer-Encoding,Base64就是其中的一种方法。在firefox你可以设置自己发送邮件的内容传输编码方式。在收到的邮件里,你可以查看邮件原文,看看原文的编码。

2.URL

有些应用需要把二进制数据放到URL里,URL只能是特定的一些ASCII字符。这时候,也需要用到BASE64编码。当然这也只是对二进制数据本身的编码,编码后的数据里面可能包含+/,真正放到URL里面时候,还需要URL-Encoding,变成%XX模式。

3.HTML中内嵌图片

就是说这种状况下,图片不是以链接地址的方式嵌到HTML中去的,图片本身已被BASE64成字符串放到HTML页面文本中去了,成为HTML文本的一部分。当HTML页面拉取完成之后,图片数据也就下来了,不再需要再去拉取图片.如下格式:

<img src='data:image/png;base64,base64code'>

这种标签图片的显示需要浏览器的支持,先Base64解码,再去显示不同格式的图片。 使用data: URI直接在网页中嵌入,data: URI定义于IETF标准的RFC 2397。 data: URI的基本使用格式如下:

data:[<MIME-type>][;base64|charset=some_charset],<data>

mime-type是嵌入数据的mime类型,比如png图片就是image/png。如果后面跟base64,说明后面的data是采用base64方式进行编码的。 获得图片的base64编码,base64编码工具不少,对于前端制作,下面这个本地图片base64编码获取页面是值得推荐的: *Encode Data URL By PuterJam *

4.简单加密

迅雷等下载工具,就有他们自己特有的下载链接,如thunder://其实就是把一个HTTP URL资源地址加上了某些东西后再进行BASE64编码,然后加上thunder://头。 垃圾讯息传播者用Base64来避过反垃圾邮件工具,因为那些工具通常都不会翻译Base64的讯息。

5.百度地图地址转化

百度地图api的地址转化(例如gps坐标->百度地图坐标)结果,使用了base64加密。

四、Java编码实现

 /**
*
* @ClassName: SecurityBase64
* @Description: 用于编码请求参数
* @author BuilderQiu
* @date 2013-9-23 上午10:52:1
*/
public class SecurityBase64 {
//对照表
private static String base64hash = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/";
//"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/";
private SecurityBase64(){}
private static class TEMP{
public static final SecurityBase64 instance = new SecurityBase64();
}
public static Security getInstance(){
return TEMP.instance;
}
private void checkSecurity(){
if("".equals(base64hash)||base64hash==null||base64hash.length()!=64){
throw new RuntimeException(Security.class+"was initialize failed!");
}
}
/**
*
* @Title: encode
* @Description: 编码
* @param @param src
* @param @return
* @return String
* @throws
*/
public String encode(String src){
checkSecurity();
StringBuilder result = new StringBuilder();
byte[] bytes = src.getBytes();
int length = bytes.length;
int mod = 0;
byte prev = 0;
for(int i=0;i<length;i++){
mod = i%3;
if(mod==0){
result.append(base64hash.charAt((bytes[i] >> 2) & 0x3F));
}else if(mod==1){
result.append(base64hash.charAt((prev << 4 | bytes[i] >> 4 &0x0F )& 0x3F));
}else{
result.append(base64hash.charAt((bytes[i] >> 6 & 0x03 | prev << 2) & 0x3F));
result.append(base64hash.charAt(bytes[i] & 0x3F));
}
prev = bytes[i];
}
if(mod==0){
result.append(base64hash.charAt(prev << 4 & 0x3C));
result.append("==");
}else if(mod==1){
result.append(base64hash.charAt(prev << 2 & 0x3F));
result.append("=");
}
return result.toString();
}
/**
*
* @Title: decode
* @Description: 解码
* @param @param src
* @param @return
* @return String
* @throws
*/
public String decode(String src){
if(StringUtil.isBlank(src)){
return "";
}
checkSecurity();
byte temp = 0;
String result = "";
for(int i=0;i<src.length();i++){
temp = (byte) base64hash.indexOf(src.charAt(i));
if(temp==-1){
result+="000000";
}else{
String t = Integer.toBinaryString(temp);
if(t.length()==7){
t = t.substring(1);
}else if(t.length()==8){
t = t.substring(2);
}
while(t.length()<6){
t = "0"+t;
}
result+=t;
}
}
while(result.endsWith("00000000")){
result = result.substring(0,result.length()-8);
}
byte[] bytes = new byte[result.length()/8];
for(int i=0;i<bytes.length;i++){
bytes[i]= Integer.valueOf(result.substring(i*8,(i+1)*8),2).byteValue();
}
return new String(bytes);
}
public void setBase64hash(String base64hash) {
Security.base64hash = base64hash;
}
/**
*
* @Title: randomTable
* @Description: 生成随机对照表
* @param @return
* @return String
* @throws
*/
public static String randomTable(){
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/";
List<Character> list = new ArrayList<Character>();
for(int i=0;i<base.length();i++){
list.add(base.charAt(i));
}
Collections.shuffle(list);
base = "";
for(Character ch:list){
base += ch;
}
return base;
}
}

Base64编码Java实现的更多相关文章

  1. Java生成BASE64编码

    1.所需jar包: BASE64Encoder.jar 2.在导包过程中,可能会出现工程不识别的情况.即:不能找到BASE64Encoder的jar包.此时,可以有两种方法解决这个问题: a.  只需 ...

  2. android Java BASE64编码和解码二:图片的编码和解码

    1.准备工作 (1)在项目中集成 Base64 代码,集成方法见第一篇博文:android Java BASE64编码和解码一:基础 (2)添加 ImgHelper 工具类 package com.a ...

  3. android Java BASE64编码和解码一:基础

    今天在做Android项目的时候遇到一个问题,需求是向服务器上传一张图片,要求把图片转化成图片流放在 json字符串里传输. 类似这样的: {"name":"jike&q ...

  4. Java Base64编码解码实现

    我尝试过两种方式:java自带的sun.misc的工具类,还有commons-codec.jar 1.sun.misc的工具类 String encoderStr = null; BASE64Enco ...

  5. java base64编码 加密和解密(切记注意乱码问题)

    BASE64 编码是一种常用的字符编码,在很多地方都会用到.JDK 中提供了非常方便的 BASE64Encoder 和 BASE64Decoder,用它们可以非常方便的完成基于 BASE64 的编码和 ...

  6. Java Base64编码与图片互转

    import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import ...

  7. Base64编码的java实现

    Java本身是提供了Base64编码的工具包的,做项目的时候自己实现了个,在这里记录一下: /** Base64编码数组 */ private static final String base64En ...

  8. java使用Base64编码和解码的图像文件

    1.编码和解码下面的代码示例看: import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import j ...

  9. JAVA 将图片转换为Base64编码

    这里使用的jar包是commons-codec-1.10.jar; 示例代码 import java.io.FileInputStream; import java.io.FileOutputStre ...

随机推荐

  1. php - preg_match

    任务:匹配一个函数名或者变量名,如果碰到alpha,numeric,_以外的全部不允许通过. 实验1: <?php //第一个字符不符合就直接退出正则匹配 $str = '%abcscript% ...

  2. TextBox只读时不能通过后台赋值取值解决办法

    给页面的TextBox设置ReadOnly="True"时,在后台代码中不能赋值取值,下边几种方法可以避免:  1.不设置ReadOnly,设置onfocus=this.blur( ...

  3. React和动态网站接口的经济学

    来自: React and the economics of dynamic web interfaces 自从2000开始我就一直在做web开发,曾见过很多以各种库和框架的起起落落,这些库和框架作为 ...

  4. Long-Polling, Websockets, SSE(Server-Sent Event), WebRTC 之间的区别

    在下面的示例中,客户端指的是浏览器,服务器指的是网站服务器主机. 为了更好的理解这些知识点,你应该简单了解典型的http网站是如何工作的. 普通的http: 客户端从服务器端请求网页 服务器作出相应的 ...

  5. 解读QML之三

    QML语法 1.QML基本语法 1.1导入声明 导入声明允许客户端告诉QML引擎可以在QML文档中使用哪些模块,JavaScript资源以及组件目录.文档中可以使用的类型依赖于在文档中导入的模块.资源 ...

  6. 使用VS软件打开网站在浏览器浏览的方法

    1.用VS软件打开网站之后,先检查网站是否使用IIS Express开发 2.若不是,则切换成使用IIS Express开发 3.检查项目使用的托管管道模式设置为经典模式了没有 4.最后选择“在浏览器 ...

  7. 关于hasnextLine()方法的一些理解

    以前对于hasnextline的理解就是 :判断是否有下一个值 今天发现了个特例,它竟然是个阻塞式的方法 看下面一个案例 这是服务器 package Service; import java.io.I ...

  8. C++11 左值与右值

    概念 左值:表达式结束后依然存在的对象 右值:表达式结束后就不存在的临时对象 2.如何判断左值和右值 能不能对表达式取地址,如果能,就是左值,否则就是右值 3.对下面的语句进行区分 int a = 3 ...

  9. java 数据结构 图

    以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客,主要是在自己理解的基础上进行记录. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示 ...

  10. POJ1182--食物链(经典并查集)并查集看不出来系列2

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 65906   Accepted: 19437 Description ...