1 57 58 package com.sun.org.apache.xerces.internal.impl.dv.util; 59 60 76 public final class Base64 { 77 78 static private final int BASELENGTH = 255; 79 static private final int LOOKUPLENGTH = 64; 80 static private final int TWENTYFOURBITGROUP = 24; 81 static private final int EIGHTBIT = 8; 82 static private final int SIXTEENBIT = 16; 83 static private final int SIXBIT = 6; 84 static private final int FOURBYTE = 4; 85 static private final int SIGN = -128; 86 static private final char PAD = '='; 87 static private final boolean fDebug = false; 88 static final private byte [] base64Alphabet = new byte[BASELENGTH]; 89 static final private char [] lookUpBase64Alphabet = new char[LOOKUPLENGTH]; 90 91 static { 92 93 for (int i = 0; i<BASELENGTH; i++) { 94 base64Alphabet[i] = -1; 95 } 96 for (int i = 'Z'; i >= 'A'; i--) { 97 base64Alphabet[i] = (byte) (i-'A'); 98 } 99 for (int i = 'z'; i>= 'a'; i--) { 100 base64Alphabet[i] = (byte) ( i-'a' + 26); 101 } 102 103 for (int i = '9'; i >= '0'; i--) { 104 base64Alphabet[i] = (byte) (i-'0' + 52); 105 } 106 107 base64Alphabet['+'] = 62; 108 base64Alphabet['/'] = 63; 109 110 for (int i = 0; i<=25; i++) 111 lookUpBase64Alphabet[i] = (char)('A'+i); 112 113 for (int i = 26, j = 0; i<=51; i++, j++) 114 lookUpBase64Alphabet[i] = (char)('a'+ j); 115 116 for (int i = 52, j = 0; i<=61; i++, j++) 117 lookUpBase64Alphabet[i] = (char)('0' + j); 118 lookUpBase64Alphabet[62] = (char)'+'; 119 lookUpBase64Alphabet[63] = (char)'/'; 120 121 } 122 123 protected static boolean isWhiteSpace(char octect) { 124 return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9); 125 } 126 127 protected static boolean isPad(char octect) { 128 return (octect == PAD); 129 } 130 131 protected static boolean isData(char octect) { 132 return (base64Alphabet[octect] != -1); 133 } 134 135 protected static boolean isBase64(char octect) { 136 return (isWhiteSpace(octect) || isPad(octect) || isData(octect)); 137 } 138 139 145 public static String encode(byte[] binaryData) { 146 147 if (binaryData == null) 148 return null; 149 150 int lengthDataBits = binaryData.length*EIGHTBIT; 151 if (lengthDataBits == 0) { 152 return ""; 153 } 154 155 int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP; 156 int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP; 157 int numberQuartet = fewerThan24bits != 0 ? numberTriplets+1 : numberTriplets; 158 int numberLines = (numberQuartet-1)/19+1; 159 char encodedData[] = null; 160 161 encodedData = new char[numberQuartet*4+numberLines]; 162 163 byte k=0, l=0, b1=0,b2=0,b3=0; 164 165 int encodedIndex = 0; 166 int dataIndex = 0; 167 int i = 0; 168 if (fDebug) { 169 System.out.println("number of triplets = " + numberTriplets ); 170 } 171 172 for (int line = 0; line < numberLines-1; line++) { 173 for (int quartet = 0; quartet < 19; quartet++) { 174 b1 = binaryData[dataIndex++]; 175 b2 = binaryData[dataIndex++]; 176 b3 = binaryData[dataIndex++]; 177 178 if (fDebug) { 179 System.out.println( "b1= " + b1 +", b2= " + b2 + ", b3= " + b3 ); 180 } 181 182 l = (byte)(b2 & 0x0f); 183 k = (byte)(b1 & 0x03); 184 185 byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); 186 187 byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); 188 byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc); 189 190 if (fDebug) { 191 System.out.println( "val2 = " + val2 ); 192 System.out.println( "k4 = " + (k<<4)); 193 System.out.println( "vak = " + (val2 | (k<<4))); 194 } 195 196 encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ]; 197 encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )]; 198 encodedData[encodedIndex++] = lookUpBase64Alphabet[ (l <<2 ) | val3 ]; 199 encodedData[encodedIndex++] = lookUpBase64Alphabet[ b3 & 0x3f ]; 200 201 i++; 202 } 203 encodedData[encodedIndex++] = 0xa; 204 } 205 206 for (; i<numberTriplets; i++) { 207 b1 = binaryData[dataIndex++]; 208 b2 = binaryData[dataIndex++]; 209 b3 = binaryData[dataIndex++]; 210 211 if (fDebug) { 212 System.out.println( "b1= " + b1 +", b2= " + b2 + ", b3= " + b3 ); 213 } 214 215 l = (byte)(b2 & 0x0f); 216 k = (byte)(b1 & 0x03); 217 218 byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); 219 220 byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); 221 byte val3 = ((b3 & SIGN)==0)?(byte)(b3>>6):(byte)((b3)>>6^0xfc); 222 223 if (fDebug) { 224 System.out.println( "val2 = " + val2 ); 225 System.out.println( "k4 = " + (k<<4)); 226 System.out.println( "vak = " + (val2 | (k<<4))); 227 } 228 229 encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ]; 230 encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )]; 231 encodedData[encodedIndex++] = lookUpBase64Alphabet[ (l <<2 ) | val3 ]; 232 encodedData[encodedIndex++] = lookUpBase64Alphabet[ b3 & 0x3f ]; 233 } 234 235 if (fewerThan24bits == EIGHTBIT) { 237 b1 = binaryData[dataIndex]; 238 k = (byte) ( b1 &0x03 ); 239 if (fDebug) { 240 System.out.println("b1=" + b1); 241 System.out.println("b1<<2 = " + (b1>>2) ); 242 } 243 byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); 244 encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ]; 245 encodedData[encodedIndex++] = lookUpBase64Alphabet[ k<<4 ]; 246 encodedData[encodedIndex++] = PAD; 247 encodedData[encodedIndex++] = PAD; 248 } else if (fewerThan24bits == SIXTEENBIT) { 249 b1 = binaryData[dataIndex]; 250 b2 = binaryData[dataIndex +1 ]; 251 l = ( byte ) ( b2 &0x0f ); 252 k = ( byte ) ( b1 &0x03 ); 253 254 byte val1 = ((b1 & SIGN)==0)?(byte)(b1>>2):(byte)((b1)>>2^0xc0); 255 byte val2 = ((b2 & SIGN)==0)?(byte)(b2>>4):(byte)((b2)>>4^0xf0); 256 257 encodedData[encodedIndex++] = lookUpBase64Alphabet[ val1 ]; 258 encodedData[encodedIndex++] = lookUpBase64Alphabet[ val2 | ( k<<4 )]; 259 encodedData[encodedIndex++] = lookUpBase64Alphabet[ l<<2 ]; 260 encodedData[encodedIndex++] = PAD; 261 } 262 263 encodedData[encodedIndex] = 0xa; 264 265 return new String (encodedData); 266 } 267 268 274 public static byte[] decode(String encoded) { 275 276 if (encoded == null) 277 return null; 278 279 char[] base64Data = encoded.toCharArray(); 280 int len = removeWhiteSpace(base64Data); 282 283 if (len%FOURBYTE != 0) { 284 return null; } 286 287 int numberQuadruple = (len/FOURBYTE ); 288 289 if (numberQuadruple == 0) 290 return new byte[0]; 291 292 byte decodedData[] = null; 293 byte b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0; 294 char d1=0,d2=0,d3=0,d4=0; 295 296 int i = 0; 297 int encodedIndex = 0; 298 int dataIndex = 0; 299 decodedData = new byte[ (numberQuadruple)*3]; 300 301 for (; i<numberQuadruple-1; i++) { 302 303 if (!isData( (d1 = base64Data[dataIndex++]) )|| 304 !isData( (d2 = base64Data[dataIndex++]) )|| 305 !isData( (d3 = base64Data[dataIndex++]) )|| 306 !isData( (d4 = base64Data[dataIndex++]) )) 307 return null; 309 b1 = base64Alphabet[d1]; 310 b2 = base64Alphabet[d2]; 311 b3 = base64Alphabet[d3]; 312 b4 = base64Alphabet[d4]; 313 314 decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ) ; 315 decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); 316 decodedData[encodedIndex++] = (byte)( b3<<6 | b4 ); 317 } 318 319 if (!isData( (d1 = base64Data[dataIndex++]) ) || 320 !isData( (d2 = base64Data[dataIndex++]) )) { 321 return null; } 323 324 b1 = base64Alphabet[d1]; 325 b2 = base64Alphabet[d2]; 326 327 d3 = base64Data[dataIndex++]; 328 d4 = base64Data[dataIndex++]; 329 if (!isData( (d3 ) ) || 330 !isData( (d4 ) )) { if (isPad( d3 ) && isPad( d4)) { if ((b2 & 0xf) != 0) return null; 334 byte[] tmp = new byte[ i*3 + 1 ]; 335 System.arraycopy( decodedData, 0, tmp, 0, i*3 ); 336 tmp[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ; 337 return tmp; 338 } else if (!isPad( d3) && isPad(d4)) { b3 = base64Alphabet[ d3 ]; 340 if ((b3 & 0x3 ) != 0) return null; 342 byte[] tmp = new byte[ i*3 + 2 ]; 343 System.arraycopy( decodedData, 0, tmp, 0, i*3 ); 344 tmp[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ); 345 tmp[encodedIndex] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); 346 return tmp; 347 } else { 348 return null; } 350 } else { b3 = base64Alphabet[ d3 ]; 352 b4 = base64Alphabet[ d4 ]; 353 decodedData[encodedIndex++] = (byte)( b1 <<2 | b2>>4 ) ; 354 decodedData[encodedIndex++] = (byte)(((b2 & 0xf)<<4 ) |( (b3>>2) & 0xf) ); 355 decodedData[encodedIndex++] = (byte)( b3<<6 | b4 ); 356 357 } 358 359 return decodedData; 360 } 361 362 368 protected static int removeWhiteSpace(char[] data) { 369 if (data == null) 370 return 0; 371 372 int newSize = 0; 374 int len = data.length; 375 for (int i = 0; i < len; i++) { 376 if (!isWhiteSpace(data[i])) 377 data[newSize++] = data[i]; 378 } 379 return newSize; 380 } 381 } 382 | Popular Tags |