用Java实现Base64的编码与转码

Base64是一种基于64个可打印字符来表示二进制数据的表示方法。
Base64常用于在通常处理文本数据的场合,表示、传输、存储一些二进制数据。包括MIME的email,email via MIME, 在XML中存储复杂数据.

Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,因此, 转换后的字节一定会落在区间[0-64)当中,故此可以找到对应基本字符表示此字节,转换后的字符串理论上将要比原来的长1/3。



public class Base64 {

/** The 64 valid Base64 characters */
private final static char[] BASE64_ALPHABET = { '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', '+', '/' };

/** The BASE64 suffix code */
private static final byte SUFFIX_CODE = '=';

private Base64() {
}

/**
* Encode a byte array into BASE64 string.
*
* @param a
* the source byte array
* @return BASE64 string
*/
public static String encode(byte[] a) {
int length = a.length;
int numOfGroups = length / 3;
int remainingBytes = length - numOfGroups * 3;
int resultLength = 4 * ((length + 2) / 3);
char[] result = new char[resultLength];
int srcIndex = 0, dstIndex = 0;

for (int i = 0; i < numOfGroups; i++) {
int byte0 = a[srcIndex++] & 0xff;
int byte1 = a[srcIndex++] & 0xff;
int byte2 = a[srcIndex++] & 0xff;
result[dstIndex++] = BASE64_ALPHABET[byte0 >> 2];
result[dstIndex++] = BASE64_ALPHABET[(byte0 << 4) & 0x30
| (byte1 >> 4)];
result[dstIndex++] = BASE64_ALPHABET[(byte1 << 2) & 0x3c
| (byte2 >> 6)];
result[dstIndex++] = BASE64_ALPHABET[byte2 & 0x3f];
}

// Process the remaining bytes
if (remainingBytes > 0) {
int byte0 = a[srcIndex++] & 0xff;
result[dstIndex++] = BASE64_ALPHABET[byte0 >> 2];
if (remainingBytes == 1) {
result[dstIndex++] = BASE64_ALPHABET[(byte0 << 4) & 0x30];
result[dstIndex++] = SUFFIX_CODE;
result[dstIndex++] = SUFFIX_CODE;
} else {
// remainingBytes == 2;
int byte1 = a[srcIndex++] & 0xff;
result[dstIndex++] = BASE64_ALPHABET[(byte0 << 4) & 0x30
| (byte1 >> 4)];
result[dstIndex++] = BASE64_ALPHABET[(byte1 << 2) & 0x3f];
result[dstIndex++] = SUFFIX_CODE;
}
}
return new String(result);
}

/**
* Decode a BASE64 string into byte array.
*
* @param s
* BASE64 string
* @return the original byte array
*/
public static byte[] decode(String s) {
if (s == null || s.length() == 0) {
return null;
}

int length = s.length();
// length must be a multiple of 4
if (length % 4 != 0) {
throw new IllegalArgumentException(
"String length must be a multiple of four.");
}

int numOfGroups = length / 4;
int numOfFullGroups = numOfGroups;
int numOfPaddings = 0;
if (s.charAt(length - 1) == SUFFIX_CODE) {
numOfPaddings++;
numOfFullGroups--;
if (s.charAt(length - 2) == SUFFIX_CODE) {
numOfPaddings++;
}
}
byte[] result = new byte[3 * numOfGroups - numOfPaddings];

int srcIndex = 0, dstIndex = 0;
for (int i = 0; i < numOfFullGroups; i++) {
int ch0 = getCharIndex(s.charAt(srcIndex++));
int ch1 = getCharIndex(s.charAt(srcIndex++));
int ch2 = getCharIndex(s.charAt(srcIndex++));
int ch3 = getCharIndex(s.charAt(srcIndex++));

result[dstIndex++] = (byte) ((ch0 << 2) | (ch1 >> 4));
result[dstIndex++] = (byte) ((ch1 << 4) | (ch2 >> 2));
result[dstIndex++] = (byte) ((ch2 << 6) | ch3);
}

if (numOfPaddings != 0) {
int ch0 = getCharIndex(s.charAt(srcIndex++));
int ch1 = getCharIndex(s.charAt(srcIndex++));
result[dstIndex++] = (byte) ((ch0 << 2) | (ch1 >> 4));
if (numOfPaddings == 1) {
int ch2 = getCharIndex(s.charAt(srcIndex++));
result[dstIndex++] = (byte) ((ch1 << 4) | (ch2 >> 2));
}
}

return result;
}

/**
* Get the index of the character in the BASE64_ALPHABET array.
*
* @param c
* @return
*/
private static int getCharIndex(char c) {
if (c >= 'A' && c <= 'Z') { // A-Z: 65-90
return (int) c - 65;
} else if (c >= 'a' && c <= 'z') { // a-z: 97-122
return (int) c - 71;
} else if (c >= '0' && c <= '9') {// 0-9: 48-57
return (int) c + 4;
} else if (c == '+') {
return 62;
} else if (c == '/') {
return 63;
}
throw new IllegalArgumentException("Character " + c
+ " is not a BASE64 char");
}

public static void main(String[] args) {

String str= "あいうえおabcde";
String buf = encode(str.getBytes());
System.out.println(buf);
byte[] result = decode(buf);
System.out.println(new String(result));
}

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值