1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/Base64.java Tue Mar 06 16:09:35 2012 -0800 1.3 @@ -0,0 +1,272 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 + 1.29 +package com.sun.xml.internal.messaging.saaj.util; 1.30 + 1.31 + 1.32 +// Cut & paste from tomcat 1.33 + 1.34 +/** 1.35 + * This class provides encode/decode for RFC 2045 Base64 as 1.36 + * defined by RFC 2045, N. Freed and N. Borenstein. 1.37 + * RFC 2045: Multipurpose Internet Mail Extensions (MIME) 1.38 + * Part One: Format of Internet Message Bodies. Reference 1.39 + * 1996 Available at: http://www.ietf.org/rfc/rfc2045.txt 1.40 + * This class is used by XML Schema binary format validation 1.41 + * 1.42 + * @author Jeffrey Rodriguez 1.43 + * @version 1.44 + */ 1.45 +public final class Base64 { 1.46 + 1.47 + 1.48 + static private final int BASELENGTH = 255; 1.49 + static private final int LOOKUPLENGTH = 63; 1.50 + static private final int TWENTYFOURBITGROUP = 24; 1.51 + static private final int EIGHTBIT = 8; 1.52 + static private final int SIXTEENBIT = 16; 1.53 + static private final int SIXBIT = 6; 1.54 + static private final int FOURBYTE = 4; 1.55 + 1.56 + 1.57 + static private final byte PAD = ( byte ) '='; 1.58 + static private byte [] base64Alphabet = new byte[BASELENGTH]; 1.59 + static private byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH]; 1.60 + 1.61 + static { 1.62 + 1.63 + for (int i = 0; i<BASELENGTH; i++ ) { 1.64 + base64Alphabet[i] = -1; 1.65 + } 1.66 + for ( int i = 'Z'; i >= 'A'; i-- ) { 1.67 + base64Alphabet[i] = (byte) (i-'A'); 1.68 + } 1.69 + for ( int i = 'z'; i>= 'a'; i--) { 1.70 + base64Alphabet[i] = (byte) ( i-'a' + 26); 1.71 + } 1.72 + 1.73 + for ( int i = '9'; i >= '0'; i--) { 1.74 + base64Alphabet[i] = (byte) (i-'0' + 52); 1.75 + } 1.76 + 1.77 + base64Alphabet['+'] = 62; 1.78 + base64Alphabet['/'] = 63; 1.79 + 1.80 + for (int i = 0; i<=25; i++ ) 1.81 + lookUpBase64Alphabet[i] = (byte) ('A'+i ); 1.82 + 1.83 + for (int i = 26, j = 0; i<=51; i++, j++ ) 1.84 + lookUpBase64Alphabet[i] = (byte) ('a'+ j ); 1.85 + 1.86 + for (int i = 52, j = 0; i<=61; i++, j++ ) 1.87 + lookUpBase64Alphabet[i] = (byte) ('0' + j ); 1.88 + 1.89 + } 1.90 + 1.91 + 1.92 + static boolean isBase64( byte octect ) { 1.93 + //shall we ignore white space? JEFF?? 1.94 + return(octect == PAD || base64Alphabet[octect] != -1 ); 1.95 + } 1.96 + 1.97 + 1.98 + static boolean isArrayByteBase64( byte[] arrayOctect ) { 1.99 + int length = arrayOctect.length; 1.100 + if ( length == 0 ) 1.101 + return false; 1.102 + for ( int i=0; i < length; i++ ) { 1.103 + if ( Base64.isBase64( arrayOctect[i] ) == false) 1.104 + return false; 1.105 + } 1.106 + return true; 1.107 + } 1.108 + 1.109 + /** 1.110 + * Encodes hex octects into Base64 1.111 + * 1.112 + * @param binaryData Array containing binaryData 1.113 + * @return Encoded Base64 array 1.114 + */ 1.115 + public static byte[] encode( byte[] binaryData ) { 1.116 + int lengthDataBits = binaryData.length*EIGHTBIT; 1.117 + int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP; 1.118 + int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP; 1.119 + byte encodedData[] = null; 1.120 + 1.121 + 1.122 + if ( fewerThan24bits != 0 ) //data not divisible by 24 bit 1.123 + encodedData = new byte[ (numberTriplets + 1 )*4 ]; 1.124 + else // 16 or 8 bit 1.125 + encodedData = new byte[ numberTriplets*4 ]; 1.126 + 1.127 + byte k=0, l=0, b1=0,b2=0,b3=0; 1.128 + 1.129 + int encodedIndex = 0; 1.130 + int dataIndex = 0; 1.131 + int i = 0; 1.132 + for ( i = 0; i<numberTriplets; i++ ) { 1.133 + 1.134 + dataIndex = i*3; 1.135 + b1 = binaryData[dataIndex]; 1.136 + b2 = binaryData[dataIndex + 1]; 1.137 + b3 = binaryData[dataIndex + 2]; 1.138 + 1.139 + l = (byte)(b2 & 0x0f); 1.140 + k = (byte)(b1 & 0x03); 1.141 + 1.142 + encodedIndex = i*4; 1.143 + encodedData[encodedIndex] = lookUpBase64Alphabet[ b1 >>2 ]; 1.144 + encodedData[encodedIndex+1] = lookUpBase64Alphabet[(b2 >>4 ) | 1.145 +( k<<4 )]; 1.146 + encodedData[encodedIndex+2] = lookUpBase64Alphabet[ (l <<2 ) | 1.147 +( b3>>6)]; 1.148 + encodedData[encodedIndex+3] = lookUpBase64Alphabet[ b3 & 0x3f ]; 1.149 + } 1.150 + 1.151 + // form integral number of 6-bit groups 1.152 + dataIndex = i*3; 1.153 + encodedIndex = i*4; 1.154 + if (fewerThan24bits == EIGHTBIT ) { 1.155 + b1 = binaryData[dataIndex]; 1.156 + k = (byte) ( b1 &0x03 ); 1.157 + encodedData[encodedIndex] = lookUpBase64Alphabet[ b1 >>2 ]; 1.158 + encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ k<<4 ]; 1.159 + encodedData[encodedIndex + 2] = PAD; 1.160 + encodedData[encodedIndex + 3] = PAD; 1.161 + } else if ( fewerThan24bits == SIXTEENBIT ) { 1.162 + 1.163 + b1 = binaryData[dataIndex]; 1.164 + b2 = binaryData[dataIndex +1 ]; 1.165 + l = ( byte ) ( b2 &0x0f ); 1.166 + k = ( byte ) ( b1 &0x03 ); 1.167 + encodedData[encodedIndex] = lookUpBase64Alphabet[ b1 >>2 ]; 1.168 + encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ (b2 >>4 ) 1.169 +| ( k<<4 )]; 1.170 + encodedData[encodedIndex + 2] = lookUpBase64Alphabet[ l<<2 ]; 1.171 + encodedData[encodedIndex + 3] = PAD; 1.172 + } 1.173 + return encodedData; 1.174 + } 1.175 + 1.176 + 1.177 + /** 1.178 + * Decodes Base64 data into octects 1.179 + * 1.180 + * @param binaryData Byte array containing Base64 data 1.181 + * @return Array containind decoded data. 1.182 + */ 1.183 + public byte[] decode( byte[] base64Data ) { 1.184 + int numberQuadruple = base64Data.length/FOURBYTE; 1.185 + byte decodedData[] = null; 1.186 + byte b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0; 1.187 + 1.188 + // Throw away anything not in base64Data 1.189 + // Adjust size 1.190 + 1.191 + int encodedIndex = 0; 1.192 + int dataIndex = 0; 1.193 + decodedData = new byte[ numberQuadruple*3 + 1 ]; 1.194 + 1.195 + for (int i = 0; i<numberQuadruple; i++ ) { 1.196 + dataIndex = i*4; 1.197 + marker0 = base64Data[dataIndex +2]; 1.198 + marker1 = base64Data[dataIndex +3]; 1.199 + 1.200 + b1 = base64Alphabet[base64Data[dataIndex]]; 1.201 + b2 = base64Alphabet[base64Data[dataIndex +1]]; 1.202 + 1.203 + if ( marker0 != PAD && marker1 != PAD ) { //No PAD e.g 3cQl 1.204 + b3 = base64Alphabet[ marker0 ]; 1.205 + b4 = base64Alphabet[ marker1 ]; 1.206 + 1.207 + decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ; 1.208 + decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |( 1.209 +(b3>>2) & 0xf) ); 1.210 + decodedData[encodedIndex+2] = (byte)( b3<<6 | b4 ); 1.211 + } else if ( marker0 == PAD ) { //Two PAD e.g. 3c[Pad][Pad] 1.212 + decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ; 1.213 + decodedData[encodedIndex+1] = (byte)((b2 & 0xf)<<4 ); 1.214 + decodedData[encodedIndex+2] = (byte) 0; 1.215 + } else if ( marker1 == PAD ) { //One PAD e.g. 3cQ[Pad] 1.216 + b3 = base64Alphabet[ marker0 ]; 1.217 + 1.218 + decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ); 1.219 + decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |( 1.220 +(b3>>2) & 0xf) ); 1.221 + decodedData[encodedIndex+2] = (byte)( b3<<6); 1.222 + } 1.223 + encodedIndex += 3; 1.224 + } 1.225 + return decodedData; 1.226 + 1.227 + } 1.228 + 1.229 + static final int base64[]= { 1.230 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 1.231 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 1.232 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 1.233 + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 1.234 + 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 1.235 + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 1.236 + 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 1.237 + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 1.238 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 1.239 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 1.240 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 1.241 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 1.242 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 1.243 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 1.244 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 1.245 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 1.246 + }; 1.247 + 1.248 + public static String base64Decode( String orig ) { 1.249 + char chars[]=orig.toCharArray(); 1.250 + StringBuffer sb=new StringBuffer(); 1.251 + int i=0; 1.252 + 1.253 + int shift = 0; // # of excess bits stored in accum 1.254 + int acc = 0; 1.255 + 1.256 + for (i=0; i<chars.length; i++) { 1.257 + int v = base64[ chars[i] & 0xFF ]; 1.258 + 1.259 + if ( v >= 64 ) { 1.260 + if( chars[i] != '=' ) 1.261 + System.out.println("Wrong char in base64: " + chars[i]); 1.262 + } else { 1.263 + acc= ( acc << 6 ) | v; 1.264 + shift += 6; 1.265 + if ( shift >= 8 ) { 1.266 + shift -= 8; 1.267 + sb.append( (char) ((acc >> shift) & 0xff)); 1.268 + } 1.269 + } 1.270 + } 1.271 + return sb.toString(); 1.272 + } 1.273 + 1.274 + 1.275 +}