Base64算法

一、介绍

Base64算法是一种基于64个字符的编码算法,仅是一种算法,并不是加密算法(因为算法是公开的)。

经过Base64编码后的数据会比原始数据略长,为原来的4/3倍。经过Base64编码后的字符串的字符数是以4为单位的整数倍。


Base64字符映射表

上图映射表中最后一个字符是等号,它是用来补位的。

Url Base64算法主要是替换了Base64字符映射表中的第62和63个字符,也就是将"+"和“/”符号替换为了"-"和“_”


二、实现原理

Base64算法主要是将给定的字符以与字符编码(ASCII码、UTF-8码)对应的十进制数为基准做编码操作:

(1)将给定的字符串以字符为单位,转为为对应的字符编码(如ASCII码)

(2)将获得的字符编码转换为二进制码

(3)对获得的二进制码做分组转换操作,每3个8位二进制码为一组,转换为4个6位二进制码为一组(不足6位时低位补0)。这是一个分组变化的过程,3个8位的二进制码和4个6位的二进制码的长度都是21位(3 x 8 = 4 x 6 = 24)

(4)对获得的4-6二进制码补位,向6位二进制码添加两位高位0,组成4个8位二进制码

(5)将获得4-8二进制码转换为十进制码

(6)将获得的十进制码转换为Base64字符表中对应的字符


例:对字符串“A”进行Base64编码

字符                                         A

ASCII码                                   65

二进制码                                 0100 0001

4-6二进制码                           010000 010000

4-8二进制码                           00010000 00010000

十进制码                                 16               16

字符表映射码                         Q                  Q               =                   =


字符串“A”经过Base64编码后得到“QQ==”这样的字符串

Base64编码后的字符串是以4个字符为单位,其长度只能是4个字符的整数倍。


示例:非ASCII码字符编码

字符                                        密

UTF-8码                                 -27                      -81                    -122

二进制码                                 11100101        10101111         10000110

4-6二进制码                           111001             011010             111110            000110

4-8二进制码                           00111001        00011010         00111110       00000110

十进制码                                 57                     26                       62                    6

字符表映射码                         5                        a                         +                      G

字符串“密”经过Base64编码后得到的字符串是“5a+G”


三、实现示例

在JAVA API中sun公司没有提供相应BASE64编码的实现;Bouncy Castle和Commons Codec(apache提供)两大开源组织包,提供了算法的实现

Bouncy Castle实现

import org.bouncycastle.util.encoders.Base64;

/**
 * Base64编码解码组件
 * 
 * @author user
 */
public abstract class Base64Coder {

	public final static String ENCODING = "UTF-8";

	public static String encode(String data) throws Exception {
		/* 执行编码 */
		byte[] b = Base64.encode(data.getBytes(ENCODING));
		return new String(b, ENCODING);
	}

	public static String decode(String data) throws Exception {
		/* 执行解码 */
		byte[] b = Base64.decode(data.getBytes(ENCODING));
		return new String(b, ENCODING);
	}
}

Commons Codec实现

import org.apache.commons.codec.binary.Base64;

public abstract class Base64Coder {

	public final static String ENCODING = "UTF-8";

	/**
	 * 一般Base64编码实现
	 */
	public static String encode(String data) throws Exception {
		/* 执行编码 */
		byte[] b = Base64.encodeBase64(data.getBytes(ENCODING));
		return new String(b, ENCODING);
	}

	/**
	 * 用于RFC 2045标准的Base64编码实现; RFC 2045定义:每行为76个字符,行末加入一个回车换行符('\r\n')
	 */
	public static String encodeSafe(String data) throws Exception {
		byte[] b = Base64.encodeBase64(data.getBytes(ENCODING), true);
		return new String(b, ENCODING);
	}

	public static String decode(String data) throws Exception {
		/* 执行解码 */
		byte[] b = Base64.decodeBase64(data.getBytes(ENCODING));
		return new String(b, ENCODING);
	}
}


四、Url Base64

符号“+”和符号“/”不允许出现在URL中,RFC 4648中给出了相应的替代符号“-”和“_”。同样,符号“=”也不允许出现在URL中。

Bouncy Castle和Commons Codec都实现了Url Base64算法,不同的是Bouncy Castle使用“.”作为填充符,而Commons Codec直接放弃了填充符,使用不定长的Url Base64编码。

Bouncy Castle实现

import org.bouncycastle.util.encoders.UrlBase64;

/**
 * URL Base64组件
 * 
 * @author user
 */
public class UrlBase64Coder {

	public static final String ENCODING = "UTF-8";

	public static String encode(String data) throws Exception {
		/* 执行编码 */
		byte[] b = UrlBase64.encode(data.getBytes(ENCODING));
		return new String(b, ENCODING);
	}

	public static String decode(String data) throws Exception {
		/* 执行解码 */
		byte[] b = UrlBase64.decode(data.getBytes(ENCODING));
		return new String(b, ENCODING);
	}
}

public class UrlBase64CoderTest {

	@Test
	public final void test() throws Exception {
		String inputStr = "Java加密与解密艺术";
		System.err.println("原文:\t" + inputStr);
		/* 进行UrlBase64编码 */
		String code = UrlBase64Coder.encode(inputStr);
		System.err.println("编码后:\t" + code);
		/* 进行UrlBase64解码 */
		String outputStr = UrlBase64Coder.decode(code);
		System.err.println("解码后:\t" + outputStr);
		/* 验证UrlBase64编码解码一致性 */
		Assert.assertEquals(inputStr, outputStr);
	}
}
输出:

原文:    Java加密与解密艺术
编码后:    SmF2YeWKoOWvhuS4juino-WvhuiJuuacrw..
解码后:    Java加密与解密艺术

--使用Base64编码后得到的是以下信息--

原文:    Java加密与解密艺术
编码后:    SmF2YeWKoOWvhuS4juino+WvhuiJuuacrw==
解码后:    Java加密与解密艺术

对比差别,发现使用Base64编码后的字符串中的“+”和“=”符号分别被替换为了“-”和“.”符号,而且没有换行的概念


Commons Codec实现

import org.apache.commons.codec.binary.Base64;

/**
 * URL Base64组件
 * 
 * @author user
 */
public class UrlBase64Coder {

	public static final String ENCODING = "UTF-8";

	public static String encode(String data) throws Exception {
		/* 执行编码 */
		byte[] b = Base64.encodeBase64URLSafe(data.getBytes(ENCODING));
		return new String(b, ENCODING);
	}

	public static String decode(String data) throws Exception {
		/* 执行解码 */
		byte[] b = Base64.decodeBase64(data.getBytes(ENCODING));
		return new String(b, ENCODING);
	}
}

public class UrlBase64CoderTest {

	@Test
	public final void test() throws Exception {
		String inputStr = "Java加密与解密艺术";
		System.err.println("原文:\t" + inputStr);
		/* 进行UrlBase64编码 */
		String code = UrlBase64Coder.encode(inputStr);
		System.err.println("编码后:\t" + code);
		/* 进行UrlBase64解码 */
		String outputStr = UrlBase64Coder.decode(code);
		System.err.println("解码后:\t" + outputStr);
		/* 验证UrlBase64编码解码一致性 */
		Assert.assertEquals(inputStr, outputStr);
	}
}

原文:    Java加密与解密艺术
编码后:    SmF2YeWKoOWvhuS4juino-WvhuiJuuacrw
解码后:    Java加密与解密艺术

Bouncy Castle方式唯一的差别是否使用“.”符号作为填充符。显然,Commons Codec使用了不定长的URL Base64编码


对于这两种实现,从实用的角度讲,通过Url参数方式传输数据往往要求数据长度尽量缩短,以缩短URL长度,避免网关限制,减少网络传输时间。从这一点将,Commons Codec的Url Base64实现较为实用。


五、应用举例

广泛应用于电子邮件的传输,以及密钥和证书文件的文本保存方式。在数据保密要求强度不高订的情况下,可以使用Base64算法做简单的数据“加密”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值