`
天使的左手
  • 浏览: 55920 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

base64编码和解码

    博客分类:
  • java
阅读更多
/**
 * 将三个8位二进制看成一组,转为4个6位二进制组,不足8位的补0, 转完后, 对应4个十进制数字, 然后可以查找base64编码表
 * (六位二进制数对应的最小十进制数是0,最大十进制数是63, 因此base64码表一共包含64个字符)进行编码
 * 
 	如果要转的字符个数不是3的倍数,则需要相应的补=
	一个字符,需要补两个= 两个字符,需要补一个=
 * 
 * 
 * 
 * 
 * 字符 			A 
 * ASCII码 		65 
 * 二进制码 		010000   01 
 * 4个6位二进制码 	010000   010000 
 * 4个8位二进制码   00010000 00010000 
 * 十进制码                          16       16 
 * 字符表映射码                  Q        Q    ==
 * 
 * RFC2045还规定每行位76个字符,每行末尾需添加一个回车换行符,即便是最后一行不够76个字符,也要加换行符。
 */
public class MyBase64 {
	private static char[] base64 = { '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', '+', '/' };

	private static byte[] convert_base64 = new byte[127];

	static {
		for (byte i = 0; i < base64.length; i++) {
			convert_base64[base64[i]] = i;// base64码表的值作为索引, 索引作为值
		}
	}

	private static final int CHUNK_LENGTH = 76;
	private static final String CHUNK_SEPARATPR = System
			.getProperty("line.separator");
	private static final String PAD = "=";

	public static byte[] decode(String base64Str) {
		char[] chs = base64Str.toCharArray();
		int i = 0, validSize = 4;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		byte[] buf = new byte[4];

		for (char c : chs) {
			if (c == '\r' || c == '\n')
				continue;

			if (c == '=')
				validSize--;
			else
				buf[i] = convert_base64[c];

			if (++i == 4) {
				switch (validSize) {
				case 2: // 包含两个=, 只对应一个字节
					baos.write(((buf[0] & 0x3F) << 2) | ((buf[1] & 0x30) >>> 4));
					break;
				case 3: // 包含一个=, 对应两个个字节
					baos.write(((buf[0] & 0x3F) << 2) | ((buf[1] & 0x30) >>> 4));
					baos.write(((buf[1] & 0x0F) << 4) | ((buf[2] & 0x3C) >>> 2));
					break;
				case 4: // 对应三个字节
					baos.write(((buf[0] & 0x3F) << 2) | ((buf[1] & 0x30) >>> 4));
					baos.write(((buf[1] & 0x0F) << 4) | ((buf[2] & 0x3C) >>> 2));
					baos.write(((buf[2] & 0x03) << 6 | (buf[3] & 0x3F)));
					break;
				}
				i = 0;
			}
		}
		return baos.toByteArray();
	}

	public static String encode(byte[] bytes, boolean isChunked) {
		int i = 0, lineSize = 0;
		byte[] buf = new byte[3];
		StringBuilder base64Str = new StringBuilder();

		for (byte b : bytes) {
			buf[i] = b;
			i++;

			// 如果存在第三个字符
			if (i == 3) {
				// 取第一个字符的前面六位, 跟0XFC(1111 1100)按位与, 再右移两位
				base64Str.append(base64[(buf[0] & 0xFC) >>> 2]);
				// 1. 取第一个字符的最后两位跟0X03(0000 0011)按位与, 左移四位
				// 2. 取第二个字符的前面四位跟0XF0(1111 0000)按位与, 右移四位
				// 3. 将第一步和第二步得到的结果做按位或, 得到六位二进制
				base64Str.append(base64[((buf[0] & 0x03) << 4)
						| ((buf[1] & 0xF0) >>> 4)]);
				// 1. 取第二个字符的最后四位跟0X0F(0000 1111)按位与, 左移2位
				// 2. 取第三个字符的前面两位跟0XC0(1100 0000)按位与, 右移六位
				// 3. 将第一步和第二步得到的结果做按位或, 得到六位二进制
				base64Str.append(base64[((buf[1] & 0x0F) << 2)
						| ((buf[2] & 0xC0) >>> 6)]);
				// 取第三个字符的最后六位跟0X3F(0011 1111)按位与
				base64Str.append(base64[(buf[2] & 0x3F)]);

				lineSize += 4;
				if (lineSize >= CHUNK_LENGTH) {
					if (isChunked)
						base64Str.append(CHUNK_SEPARATPR);
					lineSize = 0;
				}
				i = 0;
			}
		}

		// 只有一个字符
		if (i == 1) {
			base64Str.append(base64[(buf[0] & 0xFC) >>> 2]);
			base64Str.append(base64[(buf[0] & 0x03) << 4]);
			base64Str.append(PAD).append(PAD);
			lineSize += 2;
		}

		// 有两个字符
		if (i == 2) {
			base64Str.append(base64[(buf[0] & 0xFC) >>> 2]);
			base64Str.append(base64[((buf[0] & 0x03) << 4)
					| ((buf[1] & 0xF0) >>> 4)]);
			base64Str.append(base64[(buf[1] & 0x0F) << 2]);
			base64Str.append(PAD);
			lineSize += 3;
		}

		if (lineSize > 0) {
			if (isChunked)
				base64Str.append(CHUNK_SEPARATPR);
			lineSize = 0;
		}
		return base64Str.toString();
	}

	public static void main(String[] args) throws Exception {
		String s = "中华人民共和国 !!!24@#$@##&sdFSDF#@$@#$@#";
		String result = encode(s.getBytes("UTF-8"), true);
		System.out.println(result);
		System.out.println(s);

		String str = "5Lit5Y2O5Lq65rCR5YWx5ZKM5Zu9ICEhITI0QCMkQCMjJnNkRlNERiNAJEAjJEAj\r\n";
		byte[] bs = decode(str);
		System.out.println(bs.length);
		System.out.println(new String(bs, "UTF-8"));
	}

	private static void test_encode() throws UnsupportedEncodingException {
		String s = "abc";
		boolean isChuncked = false;
		// String s = "";
		// String s = "a";
		// String s = "ab";

		byte[] bytes = s.getBytes("UTF-8");
		System.out.println("=======================");
		String result = encode(bytes, isChuncked);
		System.out.println(result);
		System.out.println("=======================");
		// base64.close();

		System.out.println("=======================");
		byte[] newBytes = Base64.encodeBase64(bytes, isChuncked);
		System.out.println(new String(newBytes));
		System.out.println("=======================");
	}
}
分享到:
评论

相关推荐

    Base64编码和解码的应用(前后端程序)

    在后端,我们可以使用Java的`java.util.Base64`类进行Base64编码和解码。以下是一个简单的Servlet示例,用于接收前端发送的Base64编码字符串并解码: ```java import javax.servlet.http.*; import java.io.*; ...

    Base64 编码和解码

    在JavaScript中,Base64编码和解码是经常用到的功能,尤其是在处理图像、JSON数据或者进行跨平台通信时。 ### Base64编码原理 Base64编码的基本思想是将每3个字节(24位)的数据转换为4个6位的字符(共24位),然后...

    base64 编码与解码 中文完美支持

    中文字符在计算机中通常以多字节形式存储,因此在进行Base64编码时,需要特殊处理以确保中文字符能够正确无误地被编码和解码。"完美支持中文"意味着该Base64工具不仅能够处理ASCII字符,还能够正确处理UTF-8编码的...

    base64编码和解码c++代码

    以下将详细讨论Base64编码的原理、C++实现Base64编码和解码的步骤,以及如何从live555源码中移植和修改代码。 Base64编码原理: 1. 将每3个字节(24位)分为4个6位组。 2. 每个6位组转换为一个0-63的数字,然后用...

    Base64编码和解码器

    在这个“Base64编码和解码器”项目中,开发者可能创建了一个用户友好的界面,允许用户输入或选择一个文件,然后进行Base64编码和解码的操作。源码可能包含了对用户输入的处理,错误检查,以及如何与UI组件(如文本框...

    Java Base64编码和解码

    在Java中,处理Base64编码和解码的操作通常涉及到网络通信、数据序列化以及安全加密等方面。下面我们将详细探讨Java中的Base64编码和解码原理及其实现方式。 Base64编码的基本思想是将每3个字节(24位)的数据转换...

    Base 64编码和解码

    在提供的`base64解码`文件中,很可能是实现了Base 64编码和解码的C++代码,包括了相关的函数和可能的示例。通过阅读和理解这个代码,你可以更深入地了解Base 64的工作原理以及如何在C++中实现它。同时,这个代码也...

    Java Base64 编码和解码程序

    Java Base64 编码和解码程序,支持中文。

    C# Base64编码和解码 带源码.rar

    在C#编程中,Base64编码和解码是常见的操作,常用于处理图像、文件或加密数据。本项目提供了一个C#开发的Base64编码和解码软件,包含源码,方便开发者学习和参考。 在C#中,进行Base64编码和解码主要使用`System....

    Base64编码和解码java版本

    在Java中,Base64编码和解码的功能主要通过`java.util.Base64`这个类来实现,该类在Java 8及以上版本中引入。下面将详细介绍如何使用这个类进行Base64的编码和解码操作。 首先,我们来看Base64编码的过程。编码的...

    泉中流版base64编码和解码(支持汉字等编码(utf-8))

    `lzqDecodeBase64.py`和`lzqEncodeBase64.py`两个文件很可能是实现了自定义的Base64编码和解码功能,可能包含了一些优化或者特定的处理逻辑,例如处理UTF-8编码的汉字。 在Python中,基础的Base64编码可以使用`base...

    Base64编码和解码

    在提供的压缩包文件"Base64EncodeAndDecode"中,可能包含了实现Base64编码和解码功能的源代码。这可能是一个编程语言的库或者一个简单的命令行工具,用于将文件或字符串进行Base64的转换。源码分析和学习可以帮助...

    易语言汇编base64编码

    通过阅读和分析这些源码,你可以了解到具体是如何用易语言汇编实现Base64编码和解码的细节。这种实践经验对于深入理解易语言、汇编语言以及Base64编码机制非常有帮助。你可以学习如何在实际编程中运用这些概念和技术...

    java和js相互base64编码解码

    `调用.txt`文件可能是测试这两种编码解码方法的简单脚本,它会调用Java和JavaScript中的函数,并比较结果是否一致,确保在不同环境下的Base64编码和解码是兼容的。 总之,Java和JavaScript中Base64编码和解码的实现...

    java实现BASE64编码和解码程序

    实现BASE64编码和解码程序, 在类中实现如下函数并运行测试正确。 BASE64编码算法请在网上查询。 public String encode(byte[] data) { } public byte[] decode(String b) { }

    自己实现的Base64编码和解码,支持自定义字母表

    自己用java实现的Base64编码和解码,支持自定义字母表,文章地址http://blog.csdn.net/zzhouqianq/article/details/46992347

Global site tag (gtag.js) - Google Analytics