/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.catalina.util; import org.apache.tomcat.util.buf.ByteChunk; import org.apache.tomcat.util.buf.CharChunk; /** * This class provides encode/decode for RFC 2045 Base64 as defined by * RFC 2045, N. Freed and N. Borenstein. RFC 2045: * Multipurpose Internet Mail Extensions (MIME) Part One: Format of * Internet Message Bodies. Reference 1996 * * @author Jeffrey Rodriguez * */ public final class Base64 { static private final int BASELENGTH = 255; static private final int LOOKUPLENGTH = 64; static private final int TWENTYFOURBITGROUP = 24; static private final int EIGHTBIT = 8; static private final int SIXTEENBIT = 16; static private final int SIXBIT = 6; static private final int FOURBYTE = 4; static private final int SIGN = -128; static private final byte PAD = (byte) '='; static private byte [] base64Alphabet = new byte[BASELENGTH]; static private byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH]; //static private final Log log = LogSource.getInstance("org.apache.commons.util.Base64"); static { for (int i = 0; i < BASELENGTH; i++ ) { base64Alphabet[i] = -1; } for (int i = 'Z'; i >= 'A'; i--) { base64Alphabet[i] = (byte) (i - 'A'); } for (int i = 'z'; i>= 'a'; i--) { base64Alphabet[i] = (byte) (i - 'a' + 26); } for (int i = '9'; i >= '0'; i--) { base64Alphabet[i] = (byte) (i - '0' + 52); } base64Alphabet['+'] = 62; base64Alphabet['/'] = 63; for (int i = 0; i <= 25; i++ ) lookUpBase64Alphabet[i] = (byte) ('A' + i); for (int i = 26, j = 0; i <= 51; i++, j++ ) lookUpBase64Alphabet[i] = (byte) ('a'+ j); for (int i = 52, j = 0; i <= 61; i++, j++ ) lookUpBase64Alphabet[i] = (byte) ('0' + j); lookUpBase64Alphabet[62] = (byte) '+'; lookUpBase64Alphabet[63] = (byte) '/'; } public static boolean isBase64( String isValidString ) { return isArrayByteBase64(isValidString.getBytes()); } public static boolean isBase64( byte octect ) { //shall we ignore white space? JEFF?? return (octect == PAD || base64Alphabet[octect] != -1); } public static boolean isArrayByteBase64( byte[] arrayOctect ) { int length = arrayOctect.length; if (length == 0) { // shouldn't a 0 length array be valid base64 data? // return false; return true; } for (int i=0; i < length; i++) { if ( !Base64.isBase64(arrayOctect[i]) ) return false; } return true; } /** * Encodes hex octects into Base64. * * @param binaryData Array containing binary data to encode. * @return Base64-encoded data. */ public static byte[] encode( byte[] binaryData ) { int lengthDataBits = binaryData.length*EIGHTBIT; int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP; int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP; byte encodedData[] = null; if (fewerThan24bits != 0) { //data not divisible by 24 bit encodedData = new byte[ (numberTriplets + 1 ) * 4 ]; } else { // 16 or 8 bit encodedData = new byte[ numberTriplets * 4 ]; } byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0; int encodedIndex = 0; int dataIndex = 0; int i = 0; //log.debug("number of triplets = " + numberTriplets); for ( i = 0; i