1 57 58 package org.enhydra.apache.xerces.utils; 59 60 61 62 78 public final class Base64 { 79 static private final int BASELENGTH = 255; 80 static private final int LOOKUPLENGTH = 64; 81 static private final int TWENTYFOURBITGROUP = 24; 82 static private final int EIGHTBIT = 8; 83 static private final int SIXTEENBIT = 16; 84 static private final int SIXBIT = 6; 85 static private final int FOURBYTE = 4; 86 static private final int SIGN = -128; 87 static private final byte PAD = ( byte ) '='; 88 static private final boolean fDebug = false; 89 static private byte [] base64Alphabet = new byte[BASELENGTH]; 90 static private byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH]; 91 92 93 static { 94 95 for (int i = 0; i<BASELENGTH; i++) { 96 base64Alphabet[i] = -1; 97 } 98 for (int i = 'Z'; i >= 'A'; i--) { 99 base64Alphabet[i] = (byte) (i-'A'); 100 } 101 for (int i = 'z'; i>= 'a'; i--) { 102 base64Alphabet[i] = (byte) ( i-'a' + 26); 103 } 104 105 for (int i = '9'; i >= '0'; i--) { 106 base64Alphabet[i] = (byte) (i-'0' + 52); 107 } 108 109 base64Alphabet['+'] = 62; 110 base64Alphabet['/'] = 63; 111 112 for (int i = 0; i<=25; i++) 113 lookUpBase64Alphabet[i] = (byte) ('A'+i ); 114 115 for (int i = 26, j = 0; i<=51; i++, j++) 116 lookUpBase64Alphabet[i] = (byte) ('a'+ j ); 117 118 for (int i = 52, j = 0; i<=61; i++, j++) 119 lookUpBase64Alphabet[i] = (byte) ('0' + j ); 120 lookUpBase64Alphabet[62] = (byte) '+'; 121 lookUpBase64Alphabet[63] = (byte) '/'; 122 123 } 124 125 protected static boolean isWhiteSpace (byte octect) { 126 return(octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); 127 } 128 129 protected static boolean isPad (byte octect) { 130 return(octect == PAD); 131 } 132 133 protected static boolean isData (byte octect) { 134 return( base64Alphabet[octect] != -1); 135 } 136 137 public static boolean isBase64( String isValidString ) { 138 if (isValidString == null) 139 return false; 140 return( isArrayByteBase64( isValidString.getBytes())); 141 } 142 143 144 public static boolean isBase64( byte octect ) { 145 return( isWhiteSpace(octect) || isPad(octect) || isData(octect)); 146 } 147 148 149 159 public static synchronized byte[] removeWhiteSpace( byte[] data ) { 160 if (data == null) 161 return null; 162 163 int newSize = 0; 164 int len = data.length; 165 int i =0; 166 for (; i<len; i++) { 167 if (!isWhiteSpace( data[i] )) 168 newSize++; 169 } 170 171 if (newSize == len) 172 return data; 174 175 byte[] arrayWithoutSpaces = new byte[newSize]; 177 int j = 0; 178 for (i=0;i<len;i++) { 179 if (isWhiteSpace( data[i] )) 180 continue; 181 else 182 arrayWithoutSpaces[j++] = data[i]; } 184 return arrayWithoutSpaces; 185 186 } 187 188 public static synchronized boolean isArrayByteBase64( byte[] arrayOctect ) { 189 return(getDecodedDataLength(arrayOctect) >= 0); 190 } 191 192 198 public static synchronized byte[] encode( byte[] binaryData ) { 199 if (binaryData == null) 200 return null; 201 202 int lengthDataBits = binaryData.length*EIGHTBIT; 203 int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP; 204 int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP; 205 byte encodedData[] = null; 206 207 208 if (fewerThan24bits != 0) encodedData = new byte[ (numberTriplets + 1 )*4 ]; 210 else encodedData = new byte[ numberTriplets*4 ]; 212 213 byte k=0, l=0, b1=0,b2=0,b3=0; 214 215 int encodedIndex = 0; 216 int dataIndex = 0; 217 int i = 0; 218 if (fDebug) { 219 System.out.println("number of triplets = " + numberTriplets ); 220 } 221 for (i = 0; i<numberTriplets; i++) { 222 223 dataIndex = i*3; 224 b1 = binaryData[dataIndex]; 225 b2 = binaryData[dataIndex + 1]; 226 b3 = binaryData[dataIndex + 2]; 227 228 if (fDebug) { 229 System.out.println( "b1= " + b1 +", b2= " + b2 + ", b3= " + b3 ); 230 } 231 232 l = (byte)(b2 & 0x0f); 233 k = (byte)(b1 & 0x03); 234 235 encodedIndex = i*4; 236 byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); 237 238 byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); 239 byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc); 240 241 encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ]; 242 if (fDebug) { 243 System.out.println( "val2 = " + val2 ); 244 System.out.println( "k4 = " + (k<<4)); 245 System.out.println( "vak = " + (val2 | (k<<4))); 246 } 247 248 encodedData[encodedIndex+1] = lookUpBase64Alphabet[ val2 | ( k<<4 )]; 249 encodedData[encodedIndex+2] = lookUpBase64Alphabet[ (l <<2 ) | val3 ]; 250 encodedData[encodedIndex+3] = lookUpBase64Alphabet[ b3 & 0x3f ]; 251 } 252 253 dataIndex = i*3; 255 encodedIndex = i*4; 256 if (fewerThan24bits == EIGHTBIT) { 257 b1 = binaryData[dataIndex]; 258 k = (byte) ( b1 &0x03 ); 259 if (fDebug) { 260 System.out.println("b1=" + b1); 261 System.out.println("b1<<2 = " + (b1>>2) ); 262 } 263 byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); 264 encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ]; 265 encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ k<<4 ]; 266 encodedData[encodedIndex + 2] = PAD; 267 encodedData[encodedIndex + 3] = PAD; 268 } else if (fewerThan24bits == SIXTEENBIT) { 269 270 b1 = binaryData[dataIndex]; 271 b2 = binaryData[dataIndex +1 ]; 272 l = ( byte ) ( b2 &0x0f ); 273 k = ( byte ) ( b1 &0x03 ); 274 275 byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); 276 byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); 277 278 encodedData[encodedIndex] = lookUpBase64Alphabet[ val1 ]; 279 encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ val2 | ( k<<4 )]; 280 encodedData[encodedIndex + 2] = lookUpBase64Alphabet[ l<<2 ]; 281 encodedData[encodedIndex + 3] = PAD; 282 } 283 return encodedData; 284 } 285 286 292 public static synchronized byte[] decode( byte[] base64Data ) { 293 294 if (base64Data == null) 295 return null; 296 297 byte[] normalizedBase64Data = removeWhiteSpace( base64Data ); 298 299 if (normalizedBase64Data.length%FOURBYTE != 0) { 300 return null; } 302 303 int numberQuadruple = (normalizedBase64Data.length/FOURBYTE ); 304 305 if (numberQuadruple == 0) 306 return new byte[0]; 307 308 byte decodedData[] = null; 309 byte b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0; 310 byte d1=0,d2=0,d3=0,d4=0; 311 312 313 314 int i = 0; 317 int encodedIndex = 0; 318 int dataIndex = 0; 319 decodedData = new byte[ (numberQuadruple)*3]; 320 321 for (; i<numberQuadruple-1; i++) { 322 323 if (!isData( (d1 = normalizedBase64Data[dataIndex++]) )|| 324 !isData( (d2 = normalizedBase64Data[dataIndex++]) )|| 325 !isData( (d3 = normalizedBase64Data[dataIndex++]) )|| 326 !isData( (d4 = normalizedBase64Data[dataIndex++]) )) 327 return null; 329 b1 = base64Alphabet[d1]; 330 b2 = base64Alphabet[d2]; 331 b3 = base64Alphabet[d3]; 332 b4 = base64Alphabet[d4]; 333 334 decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ) ; 335 decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); 336 decodedData[encodedIndex++] = (byte)( b3<<6 | b4 ); 337 } 338 339 340 if (!isData( (d1 = normalizedBase64Data[dataIndex++]) ) || 341 !isData( (d2 = normalizedBase64Data[dataIndex++]) )) { 342 return null; } 344 345 346 b1 = base64Alphabet[d1]; 347 b2 = base64Alphabet[d2]; 348 349 d3 = normalizedBase64Data[dataIndex++]; 350 d4 = normalizedBase64Data[dataIndex++]; 351 if (!isData( (d3 ) ) || 352 !isData( (d4 ) )) { if (isPad( d3 ) && isPad( d4)) { if ((b2 & 0xf) != 0) return null; 356 byte[] tmp = new byte[ i*3 + 1 ]; 357 System.arraycopy( decodedData, 0, tmp, 0, i*3 ); 358 tmp[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ; 359 return tmp; 360 } else if (!isPad( d3) && isPad(d4)) { b3 = base64Alphabet[ d3 ]; 362 if ((b3 & 0x3 ) != 0) return null; 364 byte[] tmp = new byte[ i*3 + 2 ]; 365 System.arraycopy( decodedData, 0, tmp, 0, i*3 ); 366 tmp[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ); 367 tmp[encodedIndex] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); 368 return tmp; 369 } else { 370 return null; } 372 } else { b3 = base64Alphabet[ d3 ]; 374 b4 = base64Alphabet[ d4 ]; 375 decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ) ; 376 decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); 377 decodedData[encodedIndex++] = (byte)( b3<<6 | b4 ); 378 379 } 380 381 return decodedData; 382 } 383 384 385 394 static public synchronized int getDecodedDataLength( byte[] base64Data ) { 395 396 if (base64Data == null) 397 return -1; 398 399 if (base64Data.length == 0) 400 return 0; 401 402 byte[] decodedData = null; 404 405 if ((decodedData = decode( base64Data ) ) == null) return -1; 407 408 return decodedData.length; 409 } 410 } 411 | Popular Tags |