View Javadoc
1 /* 2 * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util/Base64.java,v 1.6 2003/02/07 14:38:01 jsdever Exp $ 3 * $Revision: 1.6 $ 4 * $Date: 2003/02/07 14:38:01 $ 5 * 6 * ==================================================================== 7 * 8 * The Apache Software License, Version 1.1 9 * 10 * Copyright (c) 1999-2003 The Apache Software Foundation. All rights 11 * reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in 22 * the documentation and/or other materials provided with the 23 * distribution. 24 * 25 * 3. The end-user documentation included with the redistribution, if 26 * any, must include the following acknowlegement: 27 * "This product includes software developed by the 28 * Apache Software Foundation (http://www.apache.org/)." 29 * Alternately, this acknowlegement may appear in the software itself, 30 * if and wherever such third-party acknowlegements normally appear. 31 * 32 * 4. The names "The Jakarta Project", "Commons", and "Apache Software 33 * Foundation" must not be used to endorse or promote products derived 34 * from this software without prior written permission. For written 35 * permission, please contact apache@apache.org. 36 * 37 * 5. Products derived from this software may not be called "Apache" 38 * nor may "Apache" appear in their names without prior written 39 * permission of the Apache Group. 40 * 41 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 42 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 43 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 44 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 45 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 46 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 47 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 48 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 49 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 50 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 51 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 * SUCH DAMAGE. 53 * ==================================================================== 54 * 55 * This software consists of voluntary contributions made by many 56 * individuals on behalf of the Apache Software Foundation. For more 57 * information on the Apache Software Foundation, please see 58 * <http://www.apache.org/>. 59 * 60 * [Additional notices, if required by prior licensing conditions] 61 * 62 */ 63 64 package org.apache.commons.httpclient.util; 65 66 import org.apache.commons.httpclient.HttpConstants; 67 68 /*** 69 * Base64 encoder and decoder. 70 * <p> 71 * This class provides encoding/decoding methods for the Base64 encoding as 72 * defined by RFC 2045, N. Freed and N. Borenstein. RFC 2045: Multipurpose 73 * Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies. 74 * Reference 1996. Available at: 75 * <a href="http://www.ietf.org/rfc/rfc2045.txt">http://www.ietf.org/rfc/rfc2045.txt</a> 76 * </p> 77 * 78 * @deprecated The commons-codec Base64 class will be used in HttpClient 2.1 79 * @author Jeffrey Rodriguez 80 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> 81 * @version $Revision: 1.6 $ $Date: 2003/02/07 14:38:01 $ 82 * 83 */ 84 public final class Base64 { 85 86 /*** */ 87 private static final int BASELENGTH = 255; 88 89 /*** */ 90 private static final int LOOKUPLENGTH = 64; 91 92 /*** */ 93 private static final int TWENTYFOURBITGROUP = 24; 94 95 /*** */ 96 private static final int EIGHTBIT = 8; 97 98 /*** */ 99 private static final int SIXTEENBIT = 16; 100 101 /*** */ 102 private static final int SIXBIT = 6; 103 104 /*** */ 105 private static final int FOURBYTE = 4; 106 107 /*** The sign bit as an int */ 108 private static final int SIGN = -128; 109 110 /*** The padding character */ 111 private static final byte PAD = (byte) '='; 112 113 /*** The alphabet */ 114 private static final byte [] BASE64_ALPHABET = new byte[BASELENGTH]; 115 116 /*** The lookup alphabet */ 117 private static final byte [] LOOKUP_BASE64_ALPHABET = new byte[LOOKUPLENGTH]; 118 119 static { 120 121 for (int i = 0; i < BASELENGTH; i++) { 122 BASE64_ALPHABET[i] = -1; 123 } 124 for (int i = 'Z'; i >= 'A'; i--) { 125 BASE64_ALPHABET[i] = (byte) (i - 'A'); 126 } 127 for (int i = 'z'; i >= 'a'; i--) { 128 BASE64_ALPHABET[i] = (byte) (i - 'a' + 26); 129 } 130 131 for (int i = '9'; i >= '0'; i--) { 132 BASE64_ALPHABET[i] = (byte) (i - '0' + 52); 133 } 134 135 BASE64_ALPHABET['+'] = 62; 136 BASE64_ALPHABET['/'] = 63; 137 138 for (int i = 0; i <= 25; i++) { 139 LOOKUP_BASE64_ALPHABET[i] = (byte) ('A' + i); 140 } 141 142 for (int i = 26, j = 0; i <= 51; i++, j++) { 143 LOOKUP_BASE64_ALPHABET[i] = (byte) ('a' + j); 144 } 145 146 for (int i = 52, j = 0; i <= 61; i++, j++) { 147 LOOKUP_BASE64_ALPHABET[i] = (byte) ('0' + j); 148 } 149 LOOKUP_BASE64_ALPHABET[62] = (byte) '+'; 150 LOOKUP_BASE64_ALPHABET[63] = (byte) '/'; 151 152 } 153 154 /*** 155 * Create an instance. 156 */ 157 private Base64() { 158 // the constructor is intentionally private 159 } 160 161 /*** 162 * Return true if the specified string is base64 encoded. 163 * @param isValidString The string to test. 164 * @return boolean True if the string is base64. 165 */ 166 public static boolean isBase64(String isValidString) { 167 return isArrayByteBase64(HttpConstants.getAsciiBytes(isValidString)); 168 } 169 170 171 /*** 172 * Return true if the specified octect is base64 173 * @param octect The octet to test. 174 * @return boolean True if the octect is base64. 175 */ 176 static boolean isBase64(byte octect) { 177 // Should we ignore white space? 178 return (octect == PAD || BASE64_ALPHABET[octect] != -1); 179 } 180 181 /*** 182 * Return true if the specified byte array is base64 183 * @param arrayOctect The array to test. 184 * @return boolean true if the specified byte array is base64 185 */ 186 public static boolean isArrayByteBase64(byte[] arrayOctect) { 187 int length = arrayOctect.length; 188 if (length == 0) { 189 return true; 190 } 191 for (int i = 0; i < length; i++) { 192 if (!Base64.isBase64(arrayOctect[i])) { 193 return false; 194 } 195 } 196 return true; 197 } 198 199 /*** 200 * Encodes hex octects into Base64 201 * 202 * @param binaryData Array containing binaryData 203 * @return Base64-encoded array 204 */ 205 public static byte[] encode(byte[] binaryData) { 206 207 int lengthDataBits = binaryData.length * EIGHTBIT; 208 int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP; 209 int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP; 210 byte encodedData[] = null; 211 212 213 if (fewerThan24bits != 0) { //data not divisible by 24 bit 214 encodedData = new byte[(numberTriplets + 1) * 4]; 215 } else { // 16 or 8 bit 216 encodedData = new byte[numberTriplets * 4]; 217 } 218 219 byte k = 0; 220 byte l = 0; 221 byte b1 = 0; 222 byte b2 = 0; 223 byte b3 = 0; 224 int encodedIndex = 0; 225 int dataIndex = 0; 226 int i = 0; 227 for (i = 0; i < numberTriplets; i++) { 228 229 dataIndex = i * 3; 230 b1 = binaryData[dataIndex]; 231 b2 = binaryData[dataIndex + 1]; 232 b3 = binaryData[dataIndex + 2]; 233 234 l = (byte) (b2 & 0x0f); 235 k = (byte) (b1 & 0x03); 236 237 encodedIndex = i * 4; 238 byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) 239 : (byte) ((b1) >> 2 ^ 0xc0); 240 241 byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) 242 : (byte) ((b2) >> 4 ^ 0xf0); 243 byte val3 = ((b3 & SIGN) == 0) ? (byte) (b3 >> 6) 244 : (byte) ((b3) >> 6 ^ 0xfc); 245 246 encodedData[encodedIndex] = LOOKUP_BASE64_ALPHABET[val1]; 247 encodedData[encodedIndex + 1] = LOOKUP_BASE64_ALPHABET[val2 248 | (k << 4)]; 249 encodedData[encodedIndex + 2] = LOOKUP_BASE64_ALPHABET[(l << 2) 250 | val3]; 251 encodedData[encodedIndex + 3] = LOOKUP_BASE64_ALPHABET[b3 & 0x3f]; 252 } 253 254 // form integral number of 6-bit groups 255 dataIndex = i * 3; 256 encodedIndex = i * 4; 257 if (fewerThan24bits == EIGHTBIT) { 258 b1 = binaryData[dataIndex]; 259 k = (byte) (b1 & 0x03); 260 byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) 261 : (byte) ((b1) >> 2 ^ 0xc0); 262 encodedData[encodedIndex] = LOOKUP_BASE64_ALPHABET[val1]; 263 encodedData[encodedIndex + 1] = LOOKUP_BASE64_ALPHABET[k << 4]; 264 encodedData[encodedIndex + 2] = PAD; 265 encodedData[encodedIndex + 3] = PAD; 266 } else if (fewerThan24bits == SIXTEENBIT) { 267 b1 = binaryData[dataIndex]; 268 b2 = binaryData[dataIndex + 1]; 269 l = (byte) (b2 & 0x0f); 270 k = (byte) (b1 & 0x03); 271 272 byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) 273 : (byte) ((b1) >> 2 ^ 0xc0); 274 byte val2 = ((b2 & SIGN) == 0) ? (byte) (b2 >> 4) 275 : (byte) ((b2) >> 4 ^ 0xf0); 276 277 encodedData[encodedIndex] = LOOKUP_BASE64_ALPHABET[val1]; 278 encodedData[encodedIndex + 1] = LOOKUP_BASE64_ALPHABET[val2 279 | (k << 4)]; 280 encodedData[encodedIndex + 2] = LOOKUP_BASE64_ALPHABET[l << 2]; 281 encodedData[encodedIndex + 3] = PAD; 282 } 283 return encodedData; 284 } 285 286 287 /*** 288 * Decodes Base64 data into octects 289 * 290 * @param base64Data byte array containing Base64 data 291 * @return Array containing decoded data. 292 */ 293 public static byte[] decode(byte[] base64Data) { 294 // Should we throw away anything not in base64Data ? 295 296 // handle the edge case, so we don't have to worry about it later 297 if (base64Data.length == 0) { 298 return new byte[0]; 299 } 300 301 int numberQuadruple = base64Data.length / FOURBYTE; 302 byte decodedData[] = null; 303 byte b1 = 0, b2 = 0, b3 = 0, b4 = 0, marker0 = 0, marker1 = 0; 304 305 int encodedIndex = 0; 306 int dataIndex = 0; 307 { 308 // this block sizes the output array properly - rlw 309 int lastData = base64Data.length; 310 // ignore the '=' padding 311 while (base64Data[lastData - 1] == PAD) { 312 if (--lastData == 0) { return new byte[0]; } 313 } 314 decodedData = new byte[lastData - numberQuadruple]; 315 } 316 317 for (int i = 0; i < numberQuadruple; i++) { 318 dataIndex = i * 4; 319 marker0 = base64Data[dataIndex + 2]; 320 marker1 = base64Data[dataIndex + 3]; 321 322 b1 = BASE64_ALPHABET[base64Data[dataIndex]]; 323 b2 = BASE64_ALPHABET[base64Data[dataIndex + 1]]; 324 325 if (marker0 != PAD && marker1 != PAD) { //No PAD e.g 3cQl 326 b3 = BASE64_ALPHABET[marker0]; 327 b4 = BASE64_ALPHABET[marker1]; 328 329 decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); 330 decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) 331 | ((b3 >> 2) & 0xf)); 332 decodedData[encodedIndex + 2] = (byte) (b3 << 6 | b4); 333 } else if (marker0 == PAD) { //Two PAD e.g. 3c[Pad][Pad] 334 decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4) ; 335 } else if (marker1 == PAD) { //One PAD e.g. 3cQ[Pad] 336 b3 = BASE64_ALPHABET[marker0]; 337 decodedData[encodedIndex] = (byte) (b1 << 2 | b2 >> 4); 338 decodedData[encodedIndex + 1] = (byte) (((b2 & 0xf) << 4) 339 | ((b3 >> 2) & 0xf)); 340 } 341 encodedIndex += 3; 342 } 343 return decodedData; 344 } 345 }

This page was automatically generated by Maven