📄 base64.java
字号:
* could be a sign that the data is corrupted. * * @param fIn File to be decoded. * @param fOut File to which the results should be written (may be the same as fIn). * @param throwExceptions Whether to throw exceptions when unexpected data is encountered. * @throws IOException if an IO error occurs. * @throws Base64DecodingException if unexpected data is encountered when throwExceptions is specified. * * @since ostermillerutils 1.00.00 */ public static void decode(File fIn, File fOut, boolean throwExceptions) throws IOException { File temp = null; InputStream in = null; OutputStream out = null; try { in = new BufferedInputStream(new FileInputStream(fIn)); temp = File.createTempFile("Base64", null, null); out = new BufferedOutputStream(new FileOutputStream(temp)); decode(in, out, throwExceptions); in.close(); in = null; out.flush(); out.close(); out = null; FileHelper.move(temp, fOut, true); } finally { if (in != null){ try { in.close(); } catch (IOException ignore){ if (throwExceptions) throw ignore; } in = null; } if (out != null){ try { out.flush(); out.close(); } catch (IOException ignore){ if (throwExceptions) throw ignore; } out = null; } } } /** * Reads the next (decoded) Base64 character from the input stream. * Non Base64 characters are skipped. * * @param in Stream from which bytes are read. * @param throwExceptions Throw an exception if an unexpected character is encountered. * @return the next Base64 character from the stream or -1 if there are no more Base64 characters on the stream. * @throws IOException if an IO Error occurs. * @throws Base64DecodingException if unexpected data is encountered when throwExceptions is specified. * * @since ostermillerutils 1.00.00 */ private static final int readBase64(InputStream in, boolean throwExceptions) throws IOException { int read; int numPadding = 0; do { read = in.read(); if (read == END_OF_INPUT) return END_OF_INPUT; read = reverseBase64Chars[(byte)read]; if (throwExceptions && (read == NON_BASE_64 || (numPadding > 0 && read > NON_BASE_64))){ throw new Base64DecodingException ( MessageFormat.format( labels.getString("unexpectedchar"), new String[] { "'" + (char)read + "' (0x" + Integer.toHexString(read) + ")" } ), (char)read ); } if (read == NON_BASE_64_PADDING){ numPadding++; } } while (read <= NON_BASE_64); return read; } /** * Decode Base64 encoded data from the InputStream to a byte array. * Characters that are not part of the Base64 alphabet are ignored * in the input. * * @param in Stream from which to read data that needs to be decoded. * @return decoded data. * @throws IOException if an IO error occurs. * * @since ostermillerutils 1.00.00 */ public static byte[] decodeToBytes(InputStream in) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); decode(in, out, false); return out.toByteArray(); } /** * Decode Base64 encoded data from the InputStream to a String. * Characters that are not part of the Base64 alphabet are ignored * in the input. * Bytes are converted to characters in the output String according to the platform's * default character encoding. * * @param in Stream from which to read data that needs to be decoded. * @return decoded data. * @throws IOException if an IO error occurs. * * @since ostermillerutils 1.02.16 */ public static String decodeToString(InputStream in) throws IOException { return new String(decodeToBytes(in)); } /** * Decode Base64 encoded data from the InputStream to a String. * Characters that are not part of the Base64 alphabet are ignored * in the input. * * @param in Stream from which to read data that needs to be decoded. * @param enc Character encoding to use when converting bytes to characters. * @return decoded data. * @throws IOException if an IO error occurs.Throws: * @throws UnsupportedEncodingException if the character encoding specified is not supported. * * @since ostermillerutils 1.02.16 */ public static String decodeToString(InputStream in, String enc) throws IOException { return new String(decodeToBytes(in), enc); } /** * Decode Base64 encoded data from the InputStream to the OutputStream. * Characters in the Base64 alphabet, white space and equals sign are * expected to be in urlencoded data. The presence of other characters * could be a sign that the data is corrupted. * * @param in Stream from which to read data that needs to be decoded. * @param out Stream to which to write decoded data. * @throws IOException if an IO error occurs. * @throws Base64DecodingException if unexpected data is encountered. * * @since ostermillerutils 1.00.00 */ public static void decode(InputStream in, OutputStream out) throws IOException { decode(in, out, true); } /** * Decode Base64 encoded data from the InputStream to the OutputStream. * Characters in the Base64 alphabet, white space and equals sign are * expected to be in urlencoded data. The presence of other characters * could be a sign that the data is corrupted. * * @param in Stream from which to read data that needs to be decoded. * @param out Stream to which to write decoded data. * @param throwExceptions Whether to throw exceptions when unexpected data is encountered. * @throws IOException if an IO error occurs. * @throws Base64DecodingException if unexpected data is encountered when throwExceptions is specified. * * @since ostermillerutils 1.00.00 */ public static void decode(InputStream in, OutputStream out, boolean throwExceptions) throws IOException { // Base64 decoding converts four bytes of input to three bytes of output int[] inBuffer = new int[4]; // read bytes unmapping them from their ASCII encoding in the process // we must read at least two bytes to be able to output anything boolean done = false; while (!done && (inBuffer[0] = readBase64(in, throwExceptions)) != END_OF_INPUT && (inBuffer[1] = readBase64(in, throwExceptions)) != END_OF_INPUT){ // Fill the buffer inBuffer[2] = readBase64(in, throwExceptions); inBuffer[3] = readBase64(in, throwExceptions); // Calculate the output // The first two bytes of our in buffer will always be valid // but we must check to make sure the other two bytes // are not END_OF_INPUT before using them. // The basic idea is that the four bytes will get reconstituted // into three bytes along these lines: // [xxAAAAAA] [xxBBBBBB] [xxCCCCCC] [xxDDDDDD] // [AAAAAABB] [BBBBCCCC] [CCDDDDDD] // bytes are considered to be zero when absent. // six A and two B out.write(inBuffer[0] << 2 | inBuffer[1] >> 4); if (inBuffer[2] != END_OF_INPUT){ // four B and four C out.write(inBuffer[1] << 4 | inBuffer[2] >> 2); if (inBuffer[3] != END_OF_INPUT){ // two C and six D out.write(inBuffer[2] << 6 | inBuffer[3]); } else { done = true; } } else { done = true; } } out.flush(); } /** * Determines if the byte array is in base64 format. * <p> * Data will be considered to be in base64 format if it contains * only base64 characters and whitespace with equals sign padding * on the end so that the number of base64 characters is divisible * by four. * <p> * It is possible for data to be in base64 format but for it to not * meet these stringent requirements. It is also possible for data * to meet these requirements even though decoding it would not make * any sense. This method should be used as a guide but it is not * authoritative because of the possibility of these false positives * and false negatives. * <p> * Additionally, extra data such as headers or footers may throw * this method off the scent and cause it to return false. * * @param bytes data that could be in base64 format. * * @since ostermillerutils 1.00.00 */ public static boolean isBase64(byte[] bytes){ try { return isBase64(new ByteArrayInputStream(bytes)); } catch (IOException x){ // This can't happen. // The input and output streams were constructed // on memory structures that don't actually use IO. return false; } } /** * Determines if the String is in base64 format. * The String is converted to and from bytes according to the platform's * default character encoding. * <p> * Data will be considered to be in base64 format if it contains * only base64 characters and whitespace with equals sign padding * on the end so that the number of base64 characters is divisible * by four. * <p> * It is possible for data to be in base64 format but for it to not * meet these stringent requirements. It is also possible for data * to meet these requirements even though decoding it would not make * any sense. This method should be used as a guide but it is not * authoritative because of the possibility of these false positives * and false negatives. * <p> * Additionally, extra data such as headers or footers may throw * this method off the scent and cause it to return false. * * @param string String that may be in base64 format. * @return Best guess as to whether the data is in base64 format. * * @since ostermillerutils 1.00.00 */ public static boolean isBase64(String string){ return isBase64(string.getBytes()); } /** * Determines if the String is in base64 format. * <p> * Data will be considered to be in base64 format if it contains * only base64 characters and whitespace with equals sign padding * on the end so that the number of base64 characters is divisible * by four. * <p> * It is possible for data to be in base64 format but for it to not * meet these stringent requirements. It is also possible for data * to meet these requirements even though decoding it would not make * any sense. This method should be used as a guide but it is not * authoritative because of the possibility of these false positives * and false negatives. * <p> * Additionally, extra data such as headers or footers may throw * this method off the scent and cause it to return false. * * @param string String that may be in base64 format. * @param enc Character encoding to use when converting to bytes. * @return Best guess as to whether the data is in base64 format. * @throws UnsupportedEncodingException if the character encoding specified is not supported. */ public static boolean isBase64(String string, String enc) throws UnsupportedEncodingException { return isBase64(string.getBytes(enc)); } /** * Determines if the File is in base64 format. * <p> * Data will be considered to be in base64 format if it contains * only base64 characters and whitespace with equals sign padding * on the end so that the number of base64 characters is divisible * by four. * <p> * It is possible for data to be in base64 format but for it to not * meet these stringent requirements. It is also possible for data * to meet these requirements even though decoding it would not make * any sense. This method should be used as a guide but it is not * authoritative because of the possibility of these false positives * and false negatives. * <p> * Additionally, extra data such as headers or footers may throw * this method off the scent and cause it to return false. * * @param fIn File that may be in base64 format. * @return Best guess as to whether the data is in base64 format. * @throws IOException if an IO error occurs. * * @since ostermillerutils 1.00.00 */ public static boolean isBase64(File fIn) throws IOException { return isBase64(new BufferedInputStream(new FileInputStream(fIn))); } /** * Reads data from the stream and determines if it is * in base64 format. * <p> * Data will be considered to be in base64 format if it contains * only base64 characters and whitespace with equals sign padding * on the end so that the number of base64 characters is divisible * by four. * <p> * It is possible for data to be in base64 format but for it to not * meet these stringent requirements. It is also possible for data * to meet these requirements even though decoding it would not make * any sense. This method should be used as a guide but it is not * authoritative because of the possibility of these false positives * and false negatives. * <p> * Additionally, extra data such as headers or footers may throw * this method off the scent and cause it to return false. * * @param in Stream from which to read data to be tested. * @return Best guess as to whether the data is in base64 format. * @throws IOException if an IO error occurs. * * @since ostermillerutils 1.00.00 */ public static boolean isBase64(InputStream in) throws IOException { long numBase64Chars = 0; int numPadding = 0; int read; while ((read = in.read()) != -1){ read = reverseBase64Chars[read]; if (read == NON_BASE_64){ return false; } else if (read == NON_BASE_64_WHITESPACE){ } else if (read == NON_BASE_64_PADDING){ numPadding++; numBase64Chars++; } else if (numPadding > 0){ return false; } else { numBase64Chars++; } } if (numBase64Chars == 0) return false; if (numBase64Chars % 4 != 0) return false; return true; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -