jaxws/src/java.xml.soap/share/classes/com/sun/xml/internal/messaging/saaj/util/Base64.java
changeset 28644 a70f5680dbab
parent 28643 a665e19ca007
parent 28642 a42fefc69922
child 28647 f44908f03772
equal deleted inserted replaced
28643:a665e19ca007 28644:a70f5680dbab
     1 /*
       
     2  * Copyright (c) 1997, 2013, 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 }