Filter:   InfoImg
download Base64Encoder.java
Language: Java
LOC: 153
Project Info
Enhydra Server(enhydra)
Server: ObjectWeb Forge
Type: cvs
...s\Core\src\com\lutris\util\
   Base64Encoder.java
   BMByteSearch.java
   BMByteSearchStream.java
   BytesToString.java
   ChainedError.java
   ChainedException.java
   ...edRuntimeException.java
   ChainedThrowable.java
   ChainedThrowableUtil.java
   CircularQueue.java
   Convert.java
   Currency.java
   ExceptionUtils.java
   FilePersistentStore.java
   HexEncoder.java
   HtmlEncoder.java
   JavaScriptEncoder.java
   JavaVersion.java
   LRUCache.java
   ...utStreamEventQueue.java
   ...eamEventQueueEntry.java
   OutputStreamHub.java
   PersistentStore.java
   ...tentStoreException.java
   QuotedString.java
   StringEnum.java
   TmpDir.java

/*
 * Enhydra Java Application Server Project
 * 
 * The contents of this file are subject to the Enhydra Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License on
 * the Enhydra web site ( http://www.enhydra.org/ ).
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 
 * the License for the specific terms governing rights and limitations
 * under the License.
 * 
 * The Initial Developer of the Enhydra Application Server is Lutris
 * Technologies, Inc. The Enhydra Application Server and portions created
 * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
 * All Rights Reserved.
 * 
 * Contributor(s):
 * 
 * $Id: Base64Encoder.java,v 1.15 2005/06/13 09:26:06 draganr Exp $
 */




package	com.lutris.util;
import	java.io.*;
import	java.text.*;

/**
 * Various conversion methods.
 * These methods are mostly used to convert internal java data
 * fields into byte arrays or strings for use over the network.
 *
 * @author Mike Ward
 *             
 */
public class Base64Encoder {

    /**
     * The BASE64 encoding standard's 6-bit alphabet, from RFC 1521,
     * plus the padding character at the end.
     */
    private static final char[] Base64Chars = {
	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
	'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
	'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
	'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
	'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
	'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
	'w', 'x', 'y', 'z', '0', '1', '2', '3',
	'4', '5', '6', '7', '8', '9', '+', '/',
        '='
    };

    /**
     * Encoding alphabet for session keys. Contains only chars that
     * are safe to use in cookies, URLs and file names. Same as BASE64 
     * except the last two chars and the padding char
     */
    private static final
    char[] SessionKeyChars =
    {
	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
	'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
	'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
	'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
	'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
	'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
	'w', 'x', 'y', 'z', '0', '1', '2', '3',
	'4', '5', '6', '7', '8', '9', '_', '-',
        '.'
    };

    /**
     * Performs RFC1521 style Base64 encoding of arbitrary binary data.
     * The output is a java String containing the Base64 characters 
     * representing the binary data.  Be aware that this string is in 
     * Unicode form, and should be converted to UTF8 with the usual java 
     * conversion routines before it is sent over a network.  The output 
     * string is guaranteed to only contain characters that are a single 
     * byte in UTF8 format.  Also be aware that this routine leaves it to 
     * the caller to break the string into 70 byte lines as per RFC1521.
     * 
     * @param bytes The array of bytes to convert to Base64 encoding.
     * @return	    An string containing the specified bytes in Base64
     * 		    encoded form.
     */
    public static final String toBase64String(byte[] bytes) {
        return toBase64String(bytes, Base64Chars);
    }

    /**
     * The encoding is more or less Base 64, but instead of '+'
     * and '/' as defined in RFC1521, the characters '_' and
     * '-' are used because they are safe in URLs and file names.
     * 
     * @param bytes The array of bytes to convert to Base64SessionKey 
     *              encoding.
     * @return	    An string containing the specified bytes in Base64
     * 		    encoded form.
     */
    public static final String toBase64SessionKeyString(byte[] bytes) {
        return toBase64String(bytes, SessionKeyChars);
    }
    
    /**
     * Performs encoding of arbitrary binary data based on a 6 bit
     * alphabet.  The output is a java String containing the encoded
     * characters representing the binary data.  Be aware that this
     * string is in Unicode form, and should be converted to UTF8 with
     * the usual java conversion routines before it is sent over a
     * network. The alphabet passed in via <code>chars</code> is used
     * without further checks, it's the callers responsibility to set
     * it to something meaningful.
     * 
     * @param bytes The array of bytes to convert to Base64 encoding.
     * @param chars The alphabet used in encoding. Must contain
     *              exactly 65 characters: A 6 bit alphabet plus one
     *              padding char at position 65.
     * @return	    An string containing the specified bytes in Base64
     * 		    encoded form.
     */
    private static final String toBase64String(byte[] bytes, char[] chars) {
	StringBuffer sb = new StringBuffer();
	int len = bytes.length, i=0, ival;
	while (len >= 3) {
	    ival = ((int)bytes[i++] + 256) & 0xff;
	    ival <<= 8;
	    ival += ((int)bytes[i++] + 256) & 0xff;
	    ival <<= 8;
	    ival += ((int)bytes[i++] + 256) & 0xff;
	    len -= 3;
	    sb.append(chars[(ival >> 18) & 63]);
	    sb.append(chars[(ival >> 12) & 63]);
	    sb.append(chars[(ival >> 6) & 63]);
	    sb.append(chars[ival & 63]);
	}
	switch (len) {
	    case 0:	// No pads needed.
		break;
	    case 1: // Two more output bytes and two pads.
		ival = ((int)bytes[i++] + 256) & 0xff;
		ival <<= 16;
		sb.append(chars[(ival >> 18) & 63]);
		sb.append(chars[(ival >> 12) & 63]);
		sb.append(chars[64]);
		sb.append(chars[64]);
		break;
	    case 2:	// Three more output bytes and one pad.
		ival = ((int)bytes[i++] + 256) & 0xff;
		ival <<= 8;
		ival += ((int)bytes[i] + 256) & 0xff;
		ival <<= 8;
		sb.append(chars[(ival >> 18) & 63]);
		sb.append(chars[(ival >> 12) & 63]);
		sb.append(chars[(ival >> 6) & 63]);
		sb.append(chars[64]);
		break;
	}
	return new String(sb);
    }
    
    /**
     * Performs RFC1521 style Base64 decoding of Base64 encoded data.
     * The output is a byte array containing the decoded binary data.
     * The input is expected to be a normal Unicode String object.
     * 
     * @param s The Base64 encoded string to decode into binary data.
     * @return An array of bytes containing the decoded data.
     */
    public static final byte[] fromBase64String(String s) {
	try {
	    StringCharacterIterator iter = new StringCharacterIterator(s);
	    ByteArrayOutputStream   bytestr = new ByteArrayOutputStream();
	    DataOutputStream	    outstr = new DataOutputStream(bytestr);
	    char		    c;
	    int			    d, i, group;
	    int[]		    bgroup = new int[4];
	    decode: for (i=0, group=0, c = iter.first();
			 c != CharacterIterator.DONE;
			 c = iter.next())
	    {
		switch (c) {
		    case 'A': d =  0; break; case 'B': d =  1; break;
		    case 'C': d =  2; break; case 'D': d =  3; break;
		    case 'E': d =  4; break; case 'F': d =  5; break;
		    case 'G': d =  6; break; case 'H': d =  7; break;
		    case 'I': d =  8; break; case 'J': d =  9; break;
		    case 'K': d = 10; break; case 'L': d = 11; break;
		    case 'M': d = 12; break; case 'N': d = 13; break;
		    case 'O': d = 14; break; case 'P': d = 15; break;
		    case 'Q': d = 16; break; case 'R': d = 17; break;
		    case 'S': d = 18; break; case 'T': d = 19; break;
		    case 'U': d = 20; break; case 'V': d = 21; break;
		    case 'W': d = 22; break; case 'X': d = 23; break;
		    case 'Y': d = 24; break; case 'Z': d = 25; break;
		    case 'a': d = 26; break; case 'b': d = 27; break;
		    case 'c': d = 28; break; case 'd': d = 29; break;
		    case 'e': d = 30; break; case 'f': d = 31; break;
		    case 'g': d = 32; break; case 'h': d = 33; break;
		    case 'i': d = 34; break; case 'j': d = 35; break;
		    case 'k': d = 36; break; case 'l': d = 37; break;
		    case 'm': d = 38; break; case 'n': d = 39; break;
		    case 'o': d = 40; break; case 'p': d = 41; break;
		    case 'q': d = 42; break; case 'r': d = 43; break;
		    case 's': d = 44; break; case 't': d = 45; break;
		    case 'u': d = 46; break; case 'v': d = 47; break;
		    case 'w': d = 48; break; case 'x': d = 49; break;
		    case 'y': d = 50; break; case 'z': d = 51; break;
		    case '0': d = 52; break; case '1': d = 53; break;
		    case '2': d = 54; break; case '3': d = 55; break;
		    case '4': d = 56; break; case '5': d = 57; break;
		    case '6': d = 58; break; case '7': d = 59; break;
		    case '8': d = 60; break; case '9': d = 61; break;
		    case '+': d = 62; break; case '/': d = 63; break;
		    case '_': d = 62; break; case '-': d = 63; break;
		    default:
			// Any character not in Base64 alphabet is treated
			// as end of data.  This includes the '=' (pad) char.
			break decode;   // Skip illegal characters.
		}
		bgroup[i++] = d;
		if (i >= 4) {
		    i = 0;
		    group = ((bgroup[0] & 63) << 18)+((bgroup[1] & 63) << 12)+
			    ((bgroup[2] & 63) << 6) + (bgroup[3] & 63);
		    outstr.writeByte(((group >> 16) & 255));
		    outstr.writeByte(((group >> 8) & 255));
		    outstr.writeByte(group & 255);
		}
	    }
	    // Handle the case of remaining characters and
	    // pad handling.  If input is not a multiple of 4
	    // in length, then '=' pads are assumed.
	    switch (i) {
		case 2:
		    // One output byte from two input bytes.
		    group = ((bgroup[0] & 63) << 18)+((bgroup[1] & 63) << 12);
		    outstr.writeByte(((group >> 16) & 255));
		    break;
		case 3:
		    // Two output bytes from three input bytes.
		    group = ((bgroup[0] & 63) << 18)+((bgroup[1] & 63) << 12)+
			    ((bgroup[2] & 63) << 6);
		    outstr.writeByte(((group >> 16) & 255));
		    outstr.writeByte(((group >> 8) & 255));
		    break;
		default:
		    // Any other case, including correct 0, is treated as
		    // end of data.
		    break;
	    }
	    outstr.flush();
	    return bytestr.toByteArray();
	}
	catch (IOException e) {} // Won't happen. Return null if it does.
	return null;
    }
}