001: /*
002: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003: *
004: * "The contents of this file are subject to the Mozilla Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License at
007: * http://www.mozilla.org/MPL/
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
011: * License for the specific language governing rights and limitations under
012: * the License.
013: *
014: * The Original Code is ICEfaces 1.5 open source software code, released
015: * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
016: * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
017: * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
018: *
019: * Contributor(s): _____________________.
020: *
021: * Alternatively, the contents of this file may be used under the terms of
022: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
023: * License), in which case the provisions of the LGPL License are
024: * applicable instead of those above. If you wish to allow use of your
025: * version of this file only under the terms of the LGPL License and not to
026: * allow others to use your version of this file under the MPL, indicate
027: * your decision by deleting the provisions above and replace them with
028: * the notice and other provisions required by the LGPL License. If you do
029: * not delete the provisions above, a recipient may use your version of
030: * this file under either the MPL or the LGPL License."
031: *
032: */
033:
034: package com.icesoft.util.encoding;
035:
036: /**
037: * This <code>Base64</code> is a utility class for encoding using the Base64
038: * encoding. </p>
039: *
040: * The Base64 encoding is designed to represent arbitrary sequences of octets in
041: * a form that need to be humanly readable. The encoding and decoding algorithms
042: * are simple, but the encoded data are consitently only about 33% larger than
043: * the unencoded data. </p>
044: *
045: * For more complete information about the Base64 encoding, please read <a
046: * href="http://www.ietf.org/rfc/rfc1521.txt" target="_top">MIME (Multipurpose
047: * Internet Mail Extensions) Part One</a> (Section 5.2). </p>
048: */
049: public class Base64 {
050: private static final byte[] BASE64_ALPHABET_ARRAY = { 'A', 'B',
051: 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
052: 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
053: 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
054: 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
055: 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
056: '+', '/' };
057: private static final byte[] BASE64_FOR_URL_ALPHABET_ARRAY = { 'A',
058: 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
059: 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
060: 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
061: 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
062: 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8',
063: '9', '-', '_' };
064: private static final byte PAD = '=';
065:
066: /**
067: * Encodes the specified <code>bytes</code> using the Base64 encoding. </p>
068: *
069: * @param bytes the bytes to be encoded.
070: * @return the Base64-encoded bytes.
071: * @see #encode(String)
072: */
073: public static byte[] encode(byte[] bytes) {
074: return encode(bytes, BASE64_ALPHABET_ARRAY, true);
075: }
076:
077: /**
078: * Encodes the specified <code>string</code> using the Base64 encoding. </p>
079: *
080: * @param string the string to be encoded.
081: * @return the Base64-encoded string.
082: * @see #encode(byte[])
083: */
084: public static String encode(String string) {
085: if (string == null) {
086: return null;
087: }
088: return new String(encode(string.getBytes()));
089: }
090:
091: /**
092: * Encodes the specified <code>bytes</code> using the Base64 encoding for
093: * URL usage. </p>
094: *
095: * @param bytes the bytes to be encoded.
096: * @return the Base64-encoded bytes for URL usage.
097: */
098: public static byte[] encodeForURL(byte[] bytes) {
099: return encode(bytes, BASE64_FOR_URL_ALPHABET_ARRAY, false);
100: }
101:
102: private static byte[] encode(byte[] bytes, byte[] alphabetArray,
103: boolean usePadding) {
104:
105: if (bytes == null) {
106: return null;
107: } else if (bytes.length == 0) {
108: return bytes;
109: }
110: int _length = bytes.length;
111: int _remainder = _length % 3;
112: byte[] _bytes;
113: if (usePadding) {
114: _bytes = new byte[(_length + 2) / 3 * 4];
115: } else {
116: _bytes = new byte[((_length + 2) / 3 * 4)
117: - (_remainder != 0 ? 3 - _remainder : 0)];
118: }
119: _length -= _remainder;
120: int _group;
121: int _i;
122: int _index = 0;
123: for (_i = 0; _i < _length;) {
124: _group = (bytes[_i++] & 0xFF) << 16
125: | (bytes[_i++] & 0xFF) << 8 | bytes[_i++] & 0xFF;
126: _bytes[_index++] = alphabetArray[_group >>> 18];
127: _bytes[_index++] = alphabetArray[_group >>> 12 & 0x3F];
128: _bytes[_index++] = alphabetArray[_group >>> 6 & 0x3F];
129: _bytes[_index++] = alphabetArray[_group & 0x3F];
130: }
131: switch (_remainder) {
132: case 0:
133: break;
134: case 1:
135: _group = (bytes[_i] & 0xFF) << 4;
136: _bytes[_index++] = alphabetArray[_group >>> 6];
137: if (usePadding) {
138: _bytes[_index++] = alphabetArray[_group & 0x3F];
139: _bytes[_index++] = PAD;
140: _bytes[_index] = PAD;
141: } else {
142: _bytes[_index] = alphabetArray[_group & 0x3F];
143: }
144: break;
145: case 2:
146: _group = ((bytes[_i++] & 0xFF) << 8 | (bytes[_i] & 0xFF)) << 2;
147: _bytes[_index++] = alphabetArray[_group >>> 12];
148: _bytes[_index++] = alphabetArray[_group >>> 6 & 0x3F];
149: if (usePadding) {
150: _bytes[_index++] = alphabetArray[_group & 0x3F];
151: _bytes[_index] = PAD;
152: } else {
153: _bytes[_index] = alphabetArray[_group & 0x3F];
154: }
155: break;
156: default:
157: // this should never happen.
158: }
159: return _bytes;
160: }
161: }
|