base64的java实现

本文详细解析Base64编码的原理,并提供Java版本的编码与解码实现代码,包括映射表生成与具体编码解码过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

突然想起来过去在给长春公安局的系统中短暂使用过base64图片,以过去了解的知识来看,java的base64加密不属于基础包的内容,需要额外引入rt.jar,所以今儿就看他了。


主要参考了两篇关于base64编码的原理及实现 和 Base64加密算法源码(java版)


base64编码,是可恢复的一种编码形式,编码过程如下

1. 将输入的byte数组进行分组,每3个byte一组

2. 将3个byte分组,3byte共24个bit,分成4组,每组6bit,高位用00补齐,生成4个新的byte

3. 将4个byte根据映射表对照生成新的byte数组

4. 重复1到3,如果1过程不足3个,在生成的byte数组末尾添加1到2个‘=’补齐


映射表如下

<span style="white-space:pre">			</span>encodingTable = { (byte) 'A', (byte) 'B',
			(byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
			(byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L',
			(byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q',
			(byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V',
			(byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a',
			(byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f',
			(byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k',
			(byte) 'l', (byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p',
			(byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
			(byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',
			(byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4',
			(byte) '5', (byte) '6', (byte) '7', (byte) '8', (byte) '9',
			(byte) '+', (byte) '/' };


根据编码过程,有编码的实现

	/**
	 * 
	 * @param data
	 *            输入byte数组
	 * @return 输出加密后的byte数组
	 */
	public static byte[] encode(byte[] data) {
		if (null == data)
			return null;
		int mod = data.length % 3;
		byte[] result;
		if (mod == 0) {
			result = new byte[4 * (data.length / 3)];
		} else {
			result = new byte[4 * (data.length / 3 + 1)];
		}

		int dataLength = (data.length - mod);
		int byte1;
		int byte2;
		int byte3;

		for (int i = 0, j = 0; i < dataLength; i += 3, j += 4) {
			byte1 = data[i] & 0xff;
			byte2 = data[i + 1] & 0xff;
			byte3 = data[i + 2] & 0xff;

			result[j] = encodingTable[(byte1 >> 2) & 0x3f];
			result[j + 1] = encodingTable[((byte1 << 4) | (byte2 >> 4)) & 0x3f];
			result[j + 2] = encodingTable[((byte2 << 2) | (byte3 >> 6)) & 0x3f];
			result[j + 3] = encodingTable[byte3 & 0x3f];
		}
		int last1, last2;
		switch (mod) {
		// 不需要补全=
		case 0:
			break;
		// 需要补全2个=
		case 1:
			last1 = data[data.length - 1];
			result[result.length - 4] = encodingTable[(last1 >> 2) & 0x3f];
			result[result.length - 3] = encodingTable[(last1 << 4) & 0x3f];
			result[result.length - 2] = (byte) '=';
			result[result.length - 1] = (byte) '=';
			break;
		// 需要补全1个=
		case 2:
			last2 = data[data.length - 2];
			last1 = data[data.length - 1];
			result[result.length - 4] = encodingTable[(last2 >> 2) & 0x3f];
			result[result.length - 3] = encodingTable[(last2 << 4 | last1 >> 4) & 0x3f];
			result[result.length - 2] = encodingTable[(last1 << 2) & 0x3f];
			result[result.length - 1] = (byte) '=';
			break;
		}

		return result;

	}


解密过程是编码过程的逆过程,需要注意映射表的生成

// 解密映射表
	private static byte[] decodeTable() {
		byte[] decodingTable;

		decodingTable = new byte[128];

		for (int i = 0; i < 128; i++) {
			decodingTable[i] = (byte) -1;
		}

		for (int i = 'A'; i <= 'Z'; i++) {
			decodingTable[i] = (byte) (i - 'A');
		}

		for (int i = 'a'; i <= 'z'; i++) {
			decodingTable[i] = (byte) (i - 'a' + 26);
		}

		for (int i = '0'; i <= '9'; i++) {
			decodingTable[i] = (byte) (i - '0' + 52);
		}

		decodingTable['+'] = 62;
		decodingTable['/'] = 63;

		return decodingTable;
	}

生成的映射表如下


-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 
-1 -1 -1 62 -1 -1 -1 63 52 53 
54 55 56 57 58 59 60 61 -1 -1 
-1 -1 -1 -1 -1  0  1  2  3  4 
 5  6  7  8  9 10 11 12 13 14 
15 16 17 18 19 20 21 22 23 24 
25 -1 -1 -1 -1 -1 -1 26 27 28 
29 30 31 32 33 34 35 36 37 38 
39 40 41 42 43 44 45 46 47 48 
49 50 51 -1 -1 -1 -1 -1 



解码过程代码如下

	/**
	 * 
	 * @param str
	 *            需要解码的byte数组
	 * @return 解码后的数组
	 */
	public static byte[] decode(byte[] str) {
		if (null != str && str.length % 4 != 0)
			return null;
		byte[] decodetable = decodeTable();
		int length = str.length;
		byte[] result = new byte[length * 3 / 4];
		byte byte1, byte2, byte3, byte4;
		for (int i = 0, j = 0; i < length - 4; i += 4, j += 3) {
			byte1 = decodetable[str[i]];
			byte2 = decodetable[str[i + 1]];
			byte3 = decodetable[str[i + 2]];
			byte4 = decodetable[str[i + 3]];
			result[j] = (byte) (byte1 << 2 | byte2 >> 4);
			result[j + 1] = (byte) (byte2 << 4 | byte3 >> 2);
			result[j + 2] = (byte) (byte3 << 6 | byte4);
		}
		// 存在2个=
		if (str[length - 2] == '=') {
			byte1 = decodetable[str[length - 4]];
			byte2 = decodetable[str[length - 3]];
			result[result.length - 1] = (byte) (byte1 << 2 | byte2 >> 4);
		}
		// 存在1个=
		else if (str[length - 1] == '=') {
			byte1 = decodetable[str[length - 4]];
			byte2 = decodetable[str[length - 3]];
			byte3 = decodetable[str[length - 2]];
			result[result.length - 2] = (byte) (byte1 << 2 | byte2 >> 4);
			result[result.length - 1] = (byte) (byte2 << 4 | byte3 >> 2);
		}
		// 不存在=
		else {
			byte1 = decodetable[str[length - 4]];
			byte2 = decodetable[str[length - 3]];
			byte3 = decodetable[str[length - 2]];
			byte4 = decodetable[str[length - 1]];
			result[result.length - 3] = (byte) (byte1 << 2 | byte2 >> 4);
			result[result.length - 2] = (byte) (byte2 << 4 | byte3 >> 2);
			result[result.length - 1] = (byte) (byte3 << 6 | byte4);
		}
		return result;
	}


测试

	public static void main(String[] args) {
		String str = "hello base64!";

		// 加密
		byte[] base64 = encode(str.getBytes());
		for (int i = 0; i < base64.length; i++) {
			System.out.print((char) base64[i]);
		}

		System.out.println();

		// 解密
		byte[] decode = decode(base64);
		for (int i = 0; i < decode.length; i++) {
			System.out.print((char) decode[i]);
		}
		
		System.out.println();
	}


输出结果
aGVsbG8gYmFzZTY0IQ==
hello base64!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值