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

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 368
0989ad8c0860
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2012, 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  */
    26 package com.sun.xml.internal.messaging.saaj.util;
    29 // Cut & paste from tomcat
    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 {
    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;
    54     static private final byte PAD               = ( byte ) '=';
    55     static private byte [] base64Alphabet       = new byte[BASELENGTH];
    56     static private byte [] lookUpBase64Alphabet = new byte[LOOKUPLENGTH];
    58     static {
    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         }
    70         for ( int i = '9'; i >= '0'; i--) {
    71             base64Alphabet[i] = (byte) (i-'0' + 52);
    72         }
    74         base64Alphabet['+']  = 62;
    75         base64Alphabet['/']  = 63;
    77        for (int i = 0; i<=25; i++ )
    78             lookUpBase64Alphabet[i] = (byte) ('A'+i );
    80         for (int i = 26,  j = 0; i<=51; i++, j++ )
    81             lookUpBase64Alphabet[i] = (byte) ('a'+ j );
    83         for (int i = 52,  j = 0; i<=61; i++, j++ )
    84             lookUpBase64Alphabet[i] = (byte) ('0' + j );
    86     }
    89     static boolean isBase64( byte octect ) {
    90         //shall we ignore white space? JEFF??
    91         return(octect == PAD || base64Alphabet[octect] != -1 );
    92     }
    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     }
   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;
   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 ];
   124         byte k=0, l=0, b1=0,b2=0,b3=0;
   126         int encodedIndex = 0;
   127         int dataIndex   = 0;
   128         int i           = 0;
   129         for ( i = 0; i<numberTriplets; i++ ) {
   131             dataIndex = i*3;
   132             b1 = binaryData[dataIndex];
   133             b2 = binaryData[dataIndex + 1];
   134             b3 = binaryData[dataIndex + 2];
   136             l  = (byte)(b2 & 0x0f);
   137             k  = (byte)(b1 & 0x03);
   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         }
   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 ) {
   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     }
   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;
   185         // Throw away anything not in base64Data
   186         // Adjust size
   188         int encodedIndex = 0;
   189         int dataIndex    = 0;
   190         decodedData      = new byte[ numberQuadruple*3 + 1 ];
   192         for (int i = 0; i<numberQuadruple; i++ ) {
   193             dataIndex = i*4;
   194             marker0   = base64Data[dataIndex +2];
   195             marker1   = base64Data[dataIndex +3];
   197             b1 = base64Alphabet[base64Data[dataIndex]];
   198             b2 = base64Alphabet[base64Data[dataIndex +1]];
   200             if ( marker0 != PAD && marker1 != PAD ) {     //No PAD e.g 3cQl
   201                 b3 = base64Alphabet[ marker0 ];
   202                 b4 = base64Alphabet[ marker1 ];
   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 ];
   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;
   224     }
   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     };
   245     public static String base64Decode( String orig ) {
   246         char chars[]=orig.toCharArray();
   247         StringBuffer sb=new StringBuffer();
   248         int i=0;
   250         int shift = 0;   // # of excess bits stored in accum
   251         int acc = 0;
   253         for (i=0; i<chars.length; i++) {
   254             int v = base64[ chars[i] & 0xFF ];
   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     }
   272 }

mercurial