简述
为什么叫Base64?个人理解是,基础的64个字符。
而它的作用?用基础的(可理解为可安全传输的)64个字符,来表示难以表示的二进制或对程序造成干扰的字符。
Base64的编码过程
自行编码分析Base64的编码方式
Base64的编码范围
import org.junit.Test;
public class Base64Map {
public static char[] chars = new char[64];
static {
for (int i = 0; i < 26; i++) {
chars[i] = (char)((int)'A' + i);
}
for (int i = 26; i < 52; i++) {
chars[i] = (char)((int)'a' + i - 26);
}
for (int i = 52; i < 62; i++) {
chars[i] = (char)((int)'0' + i - 52);
}
chars[62] = '+';
chars[63] = '/';
}
/**
* 获取对应的Base64字符
* @param index 下标
* @return 对应的Base64字符
*/
public static char getBase64(int index) {
return chars[index];
}
@Test
public void printAll() {
System.out.println(chars);
}
}
即:
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
简单的二进制工具
import org.junit.Test;
public class BinaryUtils {
/**
* 将多个字节转换为能打印的位
* @param b 多个字节
* @return 能打印的位
*/
public static String bytes2Bit(byte[] bytes) {
StringBuffer sb = new StringBuffer();
for (byte b : bytes) {
sb.append(BinaryUtils.byte2Bit(b));
}
return sb.toString();
}
/**
* 将字节转换为能打印的位
* @param b 字节
* @return 能打印的位
*/
public static String byte2Bit(byte b) {
/* 备注:也可用JDK方法实现:Integer.toBinaryString() */
StringBuffer sb = new StringBuffer();
for (int i = 7; i >= 0; i--) { // 右移i位
sb.append((byte) ((b >> i) & 1));
}
return sb.toString();
}
/**
* 二进制转换为十进制
* @param binary 二进制
* @return 十进制
*/
public static Integer binary2Decimal(String binary) {
if (binary == null || binary.trim().length() == 0) {
return null;
}
binary = binary.trim();
char[] chars = binary.toCharArray();
int sum = 0;
for (int i = chars.length - 1; i >= 0; i--) {
if (chars[i] == '0') {
continue;
}
sum = sum + (int)Math.pow(2, chars.length - 1 - i);
}
return sum;
}
@Test
public void bytes2BitTest() {
System.out.println(BinaryUtils.bytes2Bit("hello".getBytes()));
}
@Test
public void byte2BitTest() {
System.out.println(BinaryUtils.byte2Bit("h".getBytes()[0]));
System.out.println(Integer.toBinaryString("h".getBytes()[0]));
}
@Test
public void binary2DecimalTest() {
System.out.println(BinaryUtils.binary2Decimal("011010"));
}
}
简单的编码过程
public class Base64Analyzer {
public static void main(String[] args) {
/* TODO
* 此为练习,部分逻辑未实现:
* 1、无考虑补位到6、8的公倍数情况;
* 2、无考虑6位全部为补位,编码为=的情况
*/
/* 转换为二进制 */
String bitStr = BinaryUtils.bytes2Bit("hello".getBytes());
System.out.println(bitStr);
int bitSize = 6;
String sixBitStr = null;
Integer index = null;
char base64Char;
StringBuffer base64SB = new StringBuffer();
for (int i = 0; i < bitStr.length(); i += 6) {
/* 二进制按6位分组 */
sixBitStr = bitStr.substring(i, i + 6 > bitStr.length() ? bitStr.length() : i + 6);
if (sixBitStr.length() != 6) {
sixBitStr = sixBitStr + String.format("%0" + (bitSize - sixBitStr.length()) + "d", 0); // 不足位后补0
}
// 将每6位的字符转换为十进制
index = BinaryUtils.binary2Decimal(sixBitStr);
// 根据下标获取对应的Base64字符
base64Char = Base64Map.getBase64(index);
System.out.println(sixBitStr + " -> " + base64Char);
base64SB.append(base64Char);
}
System.out.println(base64SB.toString());
}
}
日志:
0110100001100101011011000110110001101111
011010 -> a
000110 -> G
010101 -> V
101100 -> s
011011 -> b
000110 -> G
111100 -> 8
aGVsbG8
JDK转换Base64的方式
下例是JDK1.8的方法:
import java.util.Base64;
import org.junit.Test;
public class Base64Util {
public static String encode(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}
public static byte[] decode(String s) {
return Base64.getDecoder().decode(s);
}
@Test
public void encodeTest() {
System.out.println(Base64Util.encode("hello".getBytes()));
}
@Test
public void decodeTest() {
System.out.println(new String(Base64Util.decode("aGVsbG8=")));
}
}