我的Java开发学习之旅------>Base64的编码思想以及Java实现
来源:互联网 发布:excel统计分析软件 编辑:程序博客网 时间:2024/06/18 18:25
Base64是一种用64个字符来表示任意二进制数据的方法。
用记事本打开exe、jpg、pdf这些文件时,我们都会看到一大堆乱码,因为二进制文件包含很多无法显示和打印的字符,所以,如果要让记事本这样的文本处理软件能处理二进制数据,就需要一个二进制到字符串的转换方法。Base64是一种最常见的二进制编码方法。
一、编码规则
所谓Base64,就是说选出64个字符----小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"(再加上作为垫字的"=",实际上是65个字符)----作为一个基本字符集。然后,其他所有符号都转换成这个字符集中的字符。
具体来说,转换方式可以分为四步。
- 第一步,将每三个字节作为一组,一共是24个二进制位。
- 第二步,将这24个二进制位分为四组,每个组有6个二进制位。
- 第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节。
- 第四步,根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值。
注:BASE64字符表:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
Base64 编码表 Value Char Value Char Value Char Value Char 0A16Q32g48w1B17R33h49x2C18S34i50y3D19T35j51z4E20U36k5205F21V37l5316G22W38m5427H23X39n5538I24Y40o5649J25Z41p57510K26a42q58611L27b43r59712M28c44s60813N29d45t61914O30e46u62+15P31f47v63/
因为,Base64将三个字节转化成四个字节,所以Base64编码后的文本,会比原文本大出三分之一左右。
举一个具体的实例,演示英语单词Man如何转成Base64编码。
- 第一步,"M"、"a"、"n"的ASCII值分别是77、97、110,对应的二进制值是01001101、01100001、01101110,将它们连成一个24位的二进制字符串010011010110000101101110。
- 第二步,将这个24位的二进制字符串分成4组,每组6个二进制位:010011、010110、000101、101110。
- 第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节:00010011、00010110、00000101、00101110。它们的十进制值分别是19、22、5、46。
- 第四步,根据上表,得到每个值对应Base64编码,即T、W、F、u。
因此,Man的Base64编码就是TWFu。
我们看看另外不是刚好是3个字节的情况!
xxxxxx
因此,A的Base64编码就是QQ==,BC的Base64编码就是QkM=
二、解码规则
解码过程就是把4个字节再还原成3个字节再根据不同的数据形式把字节数组重新整理成数据。
三、Java实现Base64
public class Base64Utils {/** * 将一个字节数组转换成base64的字符数组 * * @param data * 字节数组 * @return base64字符数组 */private static char[] encode(byte[] data) {char[] out = new char[((data.length + 2) / 3) * 4];for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {boolean quad = false;boolean trip = false;int val = (0xFF & (int) data[i]);val <<= 8;if ((i + 1) < data.length) {val |= (0xFF & (int) data[i + 1]);trip = true;}val <<= 8;if ((i + 2) < data.length) {val |= (0xFF & (int) data[i + 2]);quad = true;}out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];val >>= 6;out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];val >>= 6;out[index + 1] = alphabet[val & 0x3F];val >>= 6;out[index + 0] = alphabet[val & 0x3F];}return out;}/** * 将一个base64字符数组解码成一个字节数组 * * @param data * base64字符数组 * @return 返回解码以后的字节数组 */private static byte[] decode(char[] data) {int len = ((data.length + 3) / 4) * 3;if (data.length > 0 && data[data.length - 1] == '=')--len;if (data.length > 1 && data[data.length - 2] == '=')--len;byte[] out = new byte[len];int shift = 0;int accum = 0;int index = 0;for (int ix = 0; ix < data.length; ix++) {int value = codes[data[ix] & 0xFF];if (value >= 0) {accum <<= 6;shift += 6;accum |= value;if (shift >= 8) {shift -= 8;out[index++] = (byte) ((accum >> shift) & 0xff);}}}if (index != out.length)throw new Error("miscalculated data length!");return out;}/** * base64字符集 0..63 */static private char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray();/** * 初始化base64字符集表 */static private byte[] codes = new byte[256];static {for (int i = 0; i < 256; i++)codes[i] = -1;for (int i = 'A'; i <= 'Z'; i++)codes[i] = (byte) (i - 'A');for (int i = 'a'; i <= 'z'; i++)codes[i] = (byte) (26 + i - 'a');for (int i = '0'; i <= '9'; i++)codes[i] = (byte) (52 + i - '0');codes['+'] = 62;codes['/'] = 63;} /** * 将字符串通过base64转码 * @param str 要转码的字符串 * @return 返回转码后的字符串 */ public static String strToBase64Str(String str) { return new String(encode(str.getBytes())); } /** * 将base64码反转成字符串 * @param base64Str base64码 * @return 返回转码后的字符串 */ public static String base64StrToStr(String base64Str) { char[] dataArr = new char[base64Str.length()]; base64Str.getChars(0, base64Str.length(), dataArr, 0); return new String(decode(dataArr)); } /** * 将字节数组通过base64转码 * @param byteArray 字节数组 * @return 返回转码后的字符串 */ public static String byteArrayToBase64Str(byte byteArray[]) { return new String(encode(byteArray)); } /** * 将base64码转换成字节数组 * @param base64Str base64码 * @return 返回转换后的字节数组 */ public static byte[] base64StrToByteArray(String base64Str) { char[] dataArr = new char[base64Str.length()]; base64Str.getChars(0, base64Str.length(), dataArr, 0); return decode(dataArr); } /** * @param args * @throws UnsupportedEncodingException */public static void main(String[] args) throws Exception {String strSrc = "Man";String strOut = Base64Utils.strToBase64Str(strSrc);System.out.println("源字符串 "+strSrc+" 的Base64码是:"+strOut);String strOut2 = Base64Utils.base64StrToStr(strOut); System.out.println("Base64码 "+strOut+" 的对应源字符串为:"+strOut2); byte[] inByteArray={'a','b','c'}; String base64Str=Base64Utils.byteArrayToBase64Str(inByteArray); StringBuilder sb=new StringBuilder(); sb.append('['); for (int i = 0; i < inByteArray.length; i++) {sb.append(inByteArray[i]+" ");} sb.append(']'); System.out.println("字节数组:"+sb+" 的Base64码是:"+base64Str); byte[] outByteArray=Base64Utils.base64StrToByteArray(base64Str); StringBuilder sb2=new StringBuilder(); sb2.append('['); for (int i = 0; i < outByteArray.length; i++) {sb2.append(outByteArray[i]+" ");} sb2.append(']'); System.out.println("Base64码为"+base64Str+" 的对应字节数组为:"+sb2); }}
运行效果如下:
源字符串 Man 的Base64码是:TWFuBase64码 TWFu 的对应源字符串为:Man字节数组:[97 98 99 ] 的Base64码是:YWJjBase64码为YWJj 的对应字节数组为:[97 98 99 ]
====================================================================================
作者:欧阳鹏 欢迎转载,与人分享是进步的源泉!
转载请保留原文地址:http://blog.csdn.net/ouyang_peng
====================================================================================
- 我的Java开发学习之旅------>Base64的编码思想以及Java实现
- java的base64编码
- Base64编码的Java语言实现
- Base64编码与解码的java实现
- Base64编码的原理与Java实现
- 我的Java开发学习之旅------>Java字符编码解析
- 排序算法之希尔排序的思想以及Java实现
- 排序算法之冒泡排序的思想以及Java实现
- 排序算法之快速排序的思想以及Java实现
- 排序算法之选择排序的思想以及Java实现
- Base64编码java实现
- java实现base64编码
- java实现base64编码
- java编码之BASE64
- java的Base64算法详解以及Base64
- JAVA实现base64编码的三种实现方式
- Base64的java实现
- base64的java实现
- eclipse下的ssh框架整合过程及测试
- light oj 1220
- hdu 2393 Higher Math
- PowerBuilder 编绎成C语言源码
- Linux下C语言执行MySQL语句 http://www.2cto.com/database/201312/268374.html
- 我的Java开发学习之旅------>Base64的编码思想以及Java实现
- UVA156-Ananagrams
- iOS UI篇 学习笔记 UIButton,UIImageView
- 关于mysql数据库数据恢复-日志恢复
- c++对象模型
- spring mvc中的@PathVariable
- 2009 求数列的和
- 蒋炳楠:2015年9月27日开通了CSDN博客
- hdu 4000 Fruit Ninja(树状数组)