📄 base64.java
字号:
// Estimated output length (about 1.4x input, due to CRLF)
int maxChars = (binaryValueLen * 7) / 5;
// Buffer for encoded output
StringBuffer sb = new StringBuffer(maxChars);
int groupsToEOL = MAX_GROUPS_PER_LINE;
// Convert groups of 3 input bytes, with pad if < 3 in final
for (int binaryValueNdx = 0; binaryValueNdx < binaryValueLen;
binaryValueNdx += 3) {
// Encode 1st 6-bit group
int group1 = (binaryValue[binaryValueNdx] >> 2) & 0x3F;
sb.append(BASE64EncodingString.charAt(group1));
// Encode 2nd 6-bit group
int group2 = (binaryValue[binaryValueNdx] << 4) & 0x030;
if ((binaryValueNdx+1) < binaryValueLen) {
group2 = group2
| ((binaryValue[binaryValueNdx+1] >> 4) & 0xF);
}
sb.append(BASE64EncodingString.charAt(group2));
// Encode 3rd 6-bit group
int group3;
if ((binaryValueNdx+1) < binaryValueLen) {
group3 = (binaryValue[binaryValueNdx+1] << 2) & 0x03C;
if ((binaryValueNdx+2) < binaryValueLen) {
group3 = group3
| ((binaryValue[binaryValueNdx+2] >> 6) & 0x3);
}
} else {
group3 = PAD_INDEX;
}
sb.append(BASE64EncodingString.charAt(group3));
// Encode 4th 6-bit group
int group4;
if ((binaryValueNdx+2) < binaryValueLen) {
group4 = binaryValue[binaryValueNdx+2] & 0x3F;
} else {
group4 = PAD_INDEX;
}
sb.append(BASE64EncodingString.charAt(group4));
// After every MAX_GROUPS_PER_LINE groups, insert CR LF.
// Unless this is the final line, in which case we skip that.
groupsToEOL = groupsToEOL - 1;
if (groupsToEOL == 0) {
groupsToEOL = MAX_GROUPS_PER_LINE;
if ((binaryValueNdx+3) <= binaryValueLen) {
sb.append(CR);
sb.append(LF);
}
}
}
return sb.toString();
}
/**
* Initializes Base64DecodeArray, if this hasn't already been
* done.
*/
private static void initDecodeArray() {
if (Base64DecodeArray != null)
return;
int [] ourArray = new int [MAX_BASE64_CHAR+1];
for (int i = 0; i <= MAX_BASE64_CHAR; i++)
ourArray[i] = BASE64EncodingString.indexOf(i);
Base64DecodeArray = ourArray;
}
/**
* Decodes a Base64-encoded <code>String</code>. The result
* is returned in a byte array that should match the original
* binary value (before encoding). Whitespace characters
* in the input <code>String</code> are ignored.
* <p>
* If the <code>ignoreBadChars</code> parameter is
* <code>true</code>, characters that are not allowed
* in a BASE64-encoded string are ignored. Otherwise,
* they cause an <code>IOException</code> to be raised.
*
* @param encoded a <code>String</code> containing a
* Base64-encoded value
* @param ignoreBadChars If <code>true</code>, bad characters
* are ignored. Otherwise, they cause
* an <code>IOException</code> to be
* raised.
*
* @return a byte array containing the decoded value
*
* @throws IOException if the input <code>String</code> is not
* a valid Base64-encoded value
*/
public static byte[] decode(String encoded, boolean ignoreBadChars)
throws IOException
{
int encodedLen = encoded.length();
int maxBytes = (encodedLen/4)*3; /* Maximum possible output bytes */
ByteArrayOutputStream ba = /* Buffer for decoded output */
new ByteArrayOutputStream(maxBytes);
byte[] quantum = new byte[3]; /* one output quantum */
// ensure Base64DecodeArray is initialized
initDecodeArray();
/*
* Every 4 encoded characters in input are converted to 3 bytes of
* output. This is called one "quantum". Each encoded character is
* mapped to one 6-bit unit of the output. Whitespace characters in
* the input are passed over; they are not included in the output.
*/
int state = NO_CHARS_DECODED;
for (int encodedNdx = 0; encodedNdx < encodedLen; encodedNdx++) {
// Turn encoded char into decoded value
int encodedChar = encoded.charAt(encodedNdx);
int decodedChar;
if (encodedChar > MAX_BASE64_CHAR)
decodedChar = -1;
else
decodedChar = Base64DecodeArray[encodedChar];
// Handle white space and invalid characters
if (decodedChar == -1) {
if (ignoreBadChars)
continue;
throw new IOException("Invalid character");
}
if (decodedChar > PAD_INDEX) { /* whitespace */
continue;
}
// Handle valid characters
switch (state) {
case NO_CHARS_DECODED:
if (decodedChar == PAD_INDEX) {
throw new IOException("Pad character in invalid position");
}
quantum[0] = (byte) ((decodedChar << 2) & 0xFC);
state = ONE_CHAR_DECODED;
break;
case ONE_CHAR_DECODED:
if (decodedChar == PAD_INDEX) {
throw new IOException("Pad character in invalid position");
}
quantum[0] = (byte) (quantum[0] | ((decodedChar >> 4) & 0x3));
quantum[1] = (byte) ((decodedChar << 4) & 0xF0);
state = TWO_CHARS_DECODED;
break;
case TWO_CHARS_DECODED:
if (decodedChar == PAD_INDEX) {
ba.write(quantum, 0, 1);
state = PAD_THREE_READ;
} else {
quantum[1] =
(byte) (quantum[1] | ((decodedChar >> 2) & 0x0F));
quantum[2] = (byte) ((decodedChar << 6) & 0xC0);
state = THREE_CHARS_DECODED;
}
break;
case THREE_CHARS_DECODED:
if (decodedChar == PAD_INDEX) {
ba.write(quantum, 0, 2);
state = PAD_FOUR_READ;
} else {
quantum[2] = (byte) (quantum[2] | decodedChar);
ba.write(quantum, 0, 3);
state = NO_CHARS_DECODED;
}
break;
case PAD_THREE_READ:
if (decodedChar != PAD_INDEX) {
throw new IOException("Missing pad character");
}
state = PAD_FOUR_READ;
break;
case PAD_FOUR_READ:
throw new IOException("Invalid input follows pad character");
}
}
// Test valid terminal states
if (state != NO_CHARS_DECODED && state != PAD_FOUR_READ)
throw new IOException("Invalid sequence of input characters");
return ba.toByteArray();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -