src/share/jaxws_classes/com/sun/xml/internal/messaging/saaj/util/Base64.java

changeset 286
f50545b5e2f1
child 368
0989ad8c0860
equal deleted inserted replaced
284:88b85470e72c 286:f50545b5e2f1
1 /*
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.xml.internal.messaging.saaj.util;
27
28
29 // Cut & paste from tomcat
30
31 /**
32 * This class provides encode/decode for RFC 2045 Base64 as
33 * defined by RFC 2045, N. Freed and N. Borenstein.
34 * RFC 2045: Multipurpose Internet Mail Extensions (MIME)
35 * Part One: Format of Internet Message Bodies. Reference
36 * 1996 Available at: http://www.ietf.org/rfc/rfc2045.txt
37 * This class is used by XML Schema binary format validation
38 *
39 * @author Jeffrey Rodriguez
40 * @version
41 */
42 public final class Base64 {
43
44
45 static private final int BASELENGTH = 255;
46 static private final int LOOKUPLENGTH = 63;
47 static private final int TWENTYFOURBITGROUP = 24;
48 static private final int EIGHTBIT = 8;
49 static private final int SIXTEENBIT = 16;
50 static private final int SIXBIT = 6;
51 static private final int FOURBYTE = 4;
52
53
54 static private final byte PAD = ( byte ) '=';
55 static private byte [] base64Alphabet = new byte[BASELENGTH];
56 static private byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
57
58 static {
59
60 for (int i = 0; i<BASELENGTH; i++ ) {
61 base64Alphabet[i] = -1;
62 }
63 for ( int i = 'Z'; i >= 'A'; i-- ) {
64 base64Alphabet[i] = (byte) (i-'A');
65 }
66 for ( int i = 'z'; i>= 'a'; i--) {
67 base64Alphabet[i] = (byte) ( i-'a' + 26);
68 }
69
70 for ( int i = '9'; i >= '0'; i--) {
71 base64Alphabet[i] = (byte) (i-'0' + 52);
72 }
73
74 base64Alphabet['+'] = 62;
75 base64Alphabet['/'] = 63;
76
77 for (int i = 0; i<=25; i++ )
78 lookUpBase64Alphabet[i] = (byte) ('A'+i );
79
80 for (int i = 26, j = 0; i<=51; i++, j++ )
81 lookUpBase64Alphabet[i] = (byte) ('a'+ j );
82
83 for (int i = 52, j = 0; i<=61; i++, j++ )
84 lookUpBase64Alphabet[i] = (byte) ('0' + j );
85
86 }
87
88
89 static boolean isBase64( byte octect ) {
90 //shall we ignore white space? JEFF??
91 return(octect == PAD || base64Alphabet[octect] != -1 );
92 }
93
94
95 static boolean isArrayByteBase64( byte[] arrayOctect ) {
96 int length = arrayOctect.length;
97 if ( length == 0 )
98 return false;
99 for ( int i=0; i < length; i++ ) {
100 if ( Base64.isBase64( arrayOctect[i] ) == false)
101 return false;
102 }
103 return true;
104 }
105
106 /**
107 * Encodes hex octects into Base64
108 *
109 * @param binaryData Array containing binaryData
110 * @return Encoded Base64 array
111 */
112 public static byte[] encode( byte[] binaryData ) {
113 int lengthDataBits = binaryData.length*EIGHTBIT;
114 int fewerThan24bits = lengthDataBits%TWENTYFOURBITGROUP;
115 int numberTriplets = lengthDataBits/TWENTYFOURBITGROUP;
116 byte encodedData[] = null;
117
118
119 if ( fewerThan24bits != 0 ) //data not divisible by 24 bit
120 encodedData = new byte[ (numberTriplets + 1 )*4 ];
121 else // 16 or 8 bit
122 encodedData = new byte[ numberTriplets*4 ];
123
124 byte k=0, l=0, b1=0,b2=0,b3=0;
125
126 int encodedIndex = 0;
127 int dataIndex = 0;
128 int i = 0;
129 for ( i = 0; i<numberTriplets; i++ ) {
130
131 dataIndex = i*3;
132 b1 = binaryData[dataIndex];
133 b2 = binaryData[dataIndex + 1];
134 b3 = binaryData[dataIndex + 2];
135
136 l = (byte)(b2 & 0x0f);
137 k = (byte)(b1 & 0x03);
138
139 encodedIndex = i*4;
140 encodedData[encodedIndex] = lookUpBase64Alphabet[ b1 >>2 ];
141 encodedData[encodedIndex+1] = lookUpBase64Alphabet[(b2 >>4 ) |
142 ( k<<4 )];
143 encodedData[encodedIndex+2] = lookUpBase64Alphabet[ (l <<2 ) |
144 ( b3>>6)];
145 encodedData[encodedIndex+3] = lookUpBase64Alphabet[ b3 & 0x3f ];
146 }
147
148 // form integral number of 6-bit groups
149 dataIndex = i*3;
150 encodedIndex = i*4;
151 if (fewerThan24bits == EIGHTBIT ) {
152 b1 = binaryData[dataIndex];
153 k = (byte) ( b1 &0x03 );
154 encodedData[encodedIndex] = lookUpBase64Alphabet[ b1 >>2 ];
155 encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ k<<4 ];
156 encodedData[encodedIndex + 2] = PAD;
157 encodedData[encodedIndex + 3] = PAD;
158 } else if ( fewerThan24bits == SIXTEENBIT ) {
159
160 b1 = binaryData[dataIndex];
161 b2 = binaryData[dataIndex +1 ];
162 l = ( byte ) ( b2 &0x0f );
163 k = ( byte ) ( b1 &0x03 );
164 encodedData[encodedIndex] = lookUpBase64Alphabet[ b1 >>2 ];
165 encodedData[encodedIndex + 1] = lookUpBase64Alphabet[ (b2 >>4 )
166 | ( k<<4 )];
167 encodedData[encodedIndex + 2] = lookUpBase64Alphabet[ l<<2 ];
168 encodedData[encodedIndex + 3] = PAD;
169 }
170 return encodedData;
171 }
172
173
174 /**
175 * Decodes Base64 data into octects
176 *
177 * @param binaryData Byte array containing Base64 data
178 * @return Array containind decoded data.
179 */
180 public byte[] decode( byte[] base64Data ) {
181 int numberQuadruple = base64Data.length/FOURBYTE;
182 byte decodedData[] = null;
183 byte b1=0,b2=0,b3=0, b4=0, marker0=0, marker1=0;
184
185 // Throw away anything not in base64Data
186 // Adjust size
187
188 int encodedIndex = 0;
189 int dataIndex = 0;
190 decodedData = new byte[ numberQuadruple*3 + 1 ];
191
192 for (int i = 0; i<numberQuadruple; i++ ) {
193 dataIndex = i*4;
194 marker0 = base64Data[dataIndex +2];
195 marker1 = base64Data[dataIndex +3];
196
197 b1 = base64Alphabet[base64Data[dataIndex]];
198 b2 = base64Alphabet[base64Data[dataIndex +1]];
199
200 if ( marker0 != PAD && marker1 != PAD ) { //No PAD e.g 3cQl
201 b3 = base64Alphabet[ marker0 ];
202 b4 = base64Alphabet[ marker1 ];
203
204 decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
205 decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |(
206 (b3>>2) & 0xf) );
207 decodedData[encodedIndex+2] = (byte)( b3<<6 | b4 );
208 } else if ( marker0 == PAD ) { //Two PAD e.g. 3c[Pad][Pad]
209 decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 ) ;
210 decodedData[encodedIndex+1] = (byte)((b2 & 0xf)<<4 );
211 decodedData[encodedIndex+2] = (byte) 0;
212 } else if ( marker1 == PAD ) { //One PAD e.g. 3cQ[Pad]
213 b3 = base64Alphabet[ marker0 ];
214
215 decodedData[encodedIndex] = (byte)( b1 <<2 | b2>>4 );
216 decodedData[encodedIndex+1] = (byte)(((b2 & 0xf)<<4 ) |(
217 (b3>>2) & 0xf) );
218 decodedData[encodedIndex+2] = (byte)( b3<<6);
219 }
220 encodedIndex += 3;
221 }
222 return decodedData;
223
224 }
225
226 static final int base64[]= {
227 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
228 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
229 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
230 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
231 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
232 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
233 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
234 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
235 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
236 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
237 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
238 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
239 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
240 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
241 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
242 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
243 };
244
245 public static String base64Decode( String orig ) {
246 char chars[]=orig.toCharArray();
247 StringBuffer sb=new StringBuffer();
248 int i=0;
249
250 int shift = 0; // # of excess bits stored in accum
251 int acc = 0;
252
253 for (i=0; i<chars.length; i++) {
254 int v = base64[ chars[i] & 0xFF ];
255
256 if ( v >= 64 ) {
257 if( chars[i] != '=' )
258 System.out.println("Wrong char in base64: " + chars[i]);
259 } else {
260 acc= ( acc << 6 ) | v;
261 shift += 6;
262 if ( shift >= 8 ) {
263 shift -= 8;
264 sb.append( (char) ((acc >> shift) & 0xff));
265 }
266 }
267 }
268 return sb.toString();
269 }
270
271
272 }

mercurial