📄 base64.java
字号:
} /** * Encodes a byte array into Base64 notation. * * @param source The data to convert * @param off Offset in array where conversion should begin * @param len Length of data to convert * @param alphabet is the encoding alphabet * @param maxLineLength maximum length of one line. * @return the BASE64-encoded byte array */ public static byte[] encode( byte[] source, int off, int len, byte[] alphabet, int maxLineLength) { int lenDiv3 = (len + 2) / 3; // ceil(len / 3) int len43 = lenDiv3 * 4; byte[] outBuff = new byte[ ( len43 ) // Main 4:3 + ( len43 / maxLineLength ) ]; // New lines int d = 0; int e = 0; int len2 = len - 2; int lineLength = 0; for( ; d < len2; d+=3, e+=4 ) { // The following block of code is the same as // encode3to4( source, d, 3, outBuff, e, alphabet ); // but inlined for faster encoding (~20% improvement) int inBuff = ((source[ d] << 24) >>> 8) | ((source[ d + 1 ] << 24) >>> 16) | ((source[ d + 2 ] << 24) >>> 24); outBuff[ e ] = alphabet[ (inBuff >>> 18) ]; outBuff[ e + 1 ] = alphabet[ (inBuff >>> 12) & 0x3f ]; outBuff[ e + 2 ] = alphabet[ (inBuff >>> 6) & 0x3f ]; outBuff[ e + 3 ] = alphabet[ (inBuff ) & 0x3f ]; lineLength += 4; if( lineLength == maxLineLength ) { outBuff[e+4] = NEW_LINE; e++; lineLength = 0; } // end if: end of line } // end for: each piece of array if( d < len ) { encode3to4( source, d, len - d, outBuff, e, alphabet ); lineLength += 4; if( lineLength == maxLineLength ) { // Add a last newline outBuff[e+4] = NEW_LINE; e++; } e += 4; } assert(e == outBuff.length); return outBuff; } /* ******** D E C O D I N G M E T H O D S ******** */ /** * Decodes the first four bytes of array <var>fourBytes</var> * and returns an array up to three bytes long with the * decoded values. * * @param fourBytes the array with Base64 content * @param decodabet the decodabet for decoding Base64 content * @return array with decoded values * @since 1.3 */ private static byte[] decode4to3( byte[] fourBytes, byte[] decodabet ) { byte[] outBuff1 = new byte[3]; int count = decode4to3( fourBytes, 0, outBuff1, 0, decodabet ); byte[] outBuff2 = new byte[ count ]; for( int i = 0; i < count; i++ ) outBuff2[i] = outBuff1[i]; return outBuff2; } /** * Decodes four bytes from array <var>source</var> * and writes the resulting bytes (up to three of them) * to <var>destination</var>. * The source and destination arrays can be manipulated * anywhere along their length by specifying * <var>srcOffset</var> and <var>destOffset</var>. * This method does not check to make sure your arrays * are large enough to accomodate <var>srcOffset</var> + 4 for * the <var>source</var> array or <var>destOffset</var> + 3 for * the <var>destination</var> array. * This method returns the actual number of bytes that * were converted from the Base64 encoding. * * * @param source the array to convert * @param srcOffset the index where conversion begins * @param destination the array to hold the conversion * @param destOffset the index where output will be put * @param decodabet the decodabet for decoding Base64 content * @return the number of decoded bytes converted * @since 1.3 */ private static int decode4to3( byte[] source, int srcOffset, byte[] destination, int destOffset, byte[] decodabet) { // Example: Dk== if( source[ srcOffset + 2] == EQUALS_SIGN ) { int outBuff = ( ( decodabet[ source[ srcOffset ] ] << 24 ) >>> 6 ) | ( ( decodabet[ source[ srcOffset + 1] ] << 24 ) >>> 12 ); destination[ destOffset ] = (byte)( outBuff >>> 16 ); return 1; } // Example: DkL= else if( source[ srcOffset + 3 ] == EQUALS_SIGN ) { int outBuff = ( ( decodabet[ source[ srcOffset ] ] << 24 ) >>> 6 ) | ( ( decodabet[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) | ( ( decodabet[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ); destination[ destOffset ] = (byte)( outBuff >>> 16 ); destination[ destOffset + 1 ] = (byte)( outBuff >>> 8 ); return 2; } // Example: DkLE else { int outBuff = ( ( decodabet[ source[ srcOffset ] ] << 24 ) >>> 6 ) | ( ( decodabet[ source[ srcOffset + 1 ] ] << 24 ) >>> 12 ) | ( ( decodabet[ source[ srcOffset + 2 ] ] << 24 ) >>> 18 ) | ( ( decodabet[ source[ srcOffset + 3 ] ] << 24 ) >>> 24 ); destination[ destOffset ] = (byte)( outBuff >> 16 ); destination[ destOffset + 1 ] = (byte)( outBuff >> 8 ); destination[ destOffset + 2 ] = (byte)( outBuff ); return 3; } } // end decodeToBytes /** * Decodes data from Base64 notation. * * @param s the string to decode (decoded in default encoding) * @return the decoded data * @since 1.4 */ public static byte[] decode(String s) throws Base64DecoderException { byte[] bytes = s.getBytes(); return decode( bytes, 0, bytes.length ); } /** * Decodes data from web safe Base64 notation. * Web safe encoding uses '-' instead of '+', '_' instead of '/' * * @param s the string to decode (decoded in default encoding) * @return the decoded data */ public static byte[] decodeWebSafe(String s) throws Base64DecoderException { byte[] bytes = s.getBytes(); return decodeWebSafe( bytes, 0, bytes.length ); } /** * Decodes Base64 content in byte array format and returns * the decoded byte array. * * @param source The Base64 encoded data * @return decoded data * @since 1.3 * @throws Base64DecoderException */ public static byte[] decode( byte[] source ) throws Base64DecoderException { return decode(source, 0, source.length); } /** * Decodes web safe Base64 content in byte array format and returns * the decoded data. * Web safe encoding uses '-' instead of '+', '_' instead of '/' * * @param s the string to decode (decoded in default encoding) * @return the decoded data */ public static byte[] decodeWebSafe( byte[] source ) throws Base64DecoderException { return decodeWebSafe(source, 0, source.length); } /** * Decodes Base64 content in byte array format and returns * the decoded byte array. * * @param source The Base64 encoded data * @param off The offset of where to begin decoding * @param len The length of characters to decode * @return decoded data * @since 1.3 * @throws Base64DecoderException */ public static byte[] decode( byte[] source, int off, int len ) throws Base64DecoderException { return decode(source, off, len, DECODABET); } /** * Decodes web safe Base64 content in byte array format and returns * the decoded byte array. * Web safe encoding uses '-' instead of '+', '_' instead of '/' * * @param source The Base64 encoded data * @param off The offset of where to begin decoding * @param len The length of characters to decode * @return decoded data */ public static byte[] decodeWebSafe( byte[] source, int off, int len ) throws Base64DecoderException { return decode(source, off, len, WEBSAFE_DECODABET); } /** * Decodes Base64 content using the supplied decodabet and returns * the decoded byte array. * * @param source The Base64 encoded data * @param off The offset of where to begin decoding * @param len The length of characters to decode * @param decodabet the decodabet for decoding Base64 content * @return decoded data */ public static byte[] decode( byte[] source, int off, int len, byte[] decodabet) throws Base64DecoderException { int len34 = len * 3 / 4; byte[] outBuff = new byte[ 2 + len34 ]; // Upper limit on size of output int outBuffPosn = 0; byte[] b4 = new byte[4]; int b4Posn = 0; int i = 0; byte sbiCrop = 0; byte sbiDecode = 0; for( i = 0; i < len; i++ ) { sbiCrop = (byte)(source[i] & 0x7f); // Only the low seven bits sbiDecode = decodabet[ sbiCrop ]; if(sbiDecode >= WHITE_SPACE_ENC) { // White space Equals sign or better if( sbiDecode >= EQUALS_SIGN_ENC ) { // An equals sign (for padding) must not occur at position 0 or 1 // and must be the last byte[s] in the encoded value if( sbiCrop == EQUALS_SIGN ) { int bytesLeft = len - i; byte lastByte = (byte)(source[len - 1] & 0x7f); if (b4Posn == 0 || b4Posn == 1) { throw new Base64DecoderException( "invalid padding byte '=' at byte offset " + i); } else if ((b4Posn == 3 && bytesLeft > 2) || (b4Posn == 4 && bytesLeft > 1)) { throw new Base64DecoderException( "padding byte '=' falsely signals end of encoded value " + "at offset " + i); } else if (lastByte != EQUALS_SIGN && lastByte != NEW_LINE) { throw new Base64DecoderException( "encoded value has invalid trailing byte"); } break; } b4[ b4Posn++ ] = sbiCrop; if( b4Posn == 4 ) { outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet); b4Posn = 0; } } } else { throw new Base64DecoderException( "Bad Base64 input character at " + i + ": " + source[i] + "(decimal)"); } } // Because web safe encoding allows non padding base64 encodes, we // need to pad the rest of the b4 buffer with equal signs when // b4Posn != 0. There can be at most 2 equal signs at the end of // four characters, so the b4 buffer must have two or three // characters. This also catches the case where the input is // padded with EQUALS_SIGN if (b4Posn != 0) { if (b4Posn == 1) { throw new Base64DecoderException( "single trailing character at offset " + (len - 1)); } b4[ b4Posn++ ] = EQUALS_SIGN; outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet); } byte[] out = new byte[ outBuffPosn ]; System.arraycopy( outBuff, 0, out, 0, outBuffPosn ); return out; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -