All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.oodt.commons.util.Base64 Maven / Gradle / Ivy

There is a newer version: 1.9.1
Show newest version
// Licensed to the Apache Software Foundation (ASF) under one or more contributor
// license agreements.  See the NOTICE.txt file distributed with this work for
// additional information regarding copyright ownership.  The ASF licenses this
// file to you under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License.  You may obtain a copy of
// the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
// License for the specific language governing permissions and limitations under
// the License.

package org.apache.oodt.commons.util;

import java.io.*;
import org.apache.oodt.commons.io.*;

/** Base 64 encoding and decoding.
 *
 * This class provides methods for RFC-1521 specified "base 64" encoding and decoding of
 * arbitrary data.  Pass a byte array into the {@link #encode} method and you'll get a
 * byte array result where all of the bytes are printable ASCII values.  Pass that result
 * into {@link #decode} and you'll get your original byte array.
 *
 * 

Sincere thanks to Tom Daley for providing a sample encoder algorithm and a great * explanation of how RFC-1521 is supposed to work. * * @author Kelly */ public class Base64 { /** Encode into base 64. * * Encode the given data into RFC-1521 base 64. Encoding a null array gives a * null result. * * @param data The data to encode. * @return Base-64 encoded data. */ public static byte[] encode(final byte[] data) { return encode(data, 0, data.length); } /** Encode into base 64. * * Encode the given data into RFC-1521 base 64. Encoding a null array gives a * null result. Start encoding at the given offset and go for the given amount of * bytes. * * @param data The data to encode. * @param offset Where to start looking for data to encode. * @param length How much data to encode. * @return Base-64 encoded data */ public static byte[] encode(final byte[] data, int offset, int length) { if (data == null) return null; if (offset < 0 || offset > data.length) throw new IndexOutOfBoundsException("Can't encode at index " + offset + " which is beyond array bounds 0.." + data.length); if (length < 0) throw new IllegalArgumentException("Can't encode a negative amount of data"); if (offset + length > data.length) throw new IndexOutOfBoundsException("Can't encode beyond right edge of array"); int i, j; byte dest[] = new byte[((length+2)/3)*4]; // Convert groups of 3 bytes into 4. for (i = 0 + offset, j = 0; i < offset + length - 2; i += 3) { dest[j++] = (byte) ((data[i] >>> 2) & 077); dest[j++] = (byte) ((data[i+1] >>> 4) & 017 | (data[i] << 4) & 077); dest[j++] = (byte) ((data[i+2] >>> 6) & 003 | (data[i+1] << 2) & 077); dest[j++] = (byte) (data[i+2] & 077); } // Convert any leftover bytes. if (i < offset + length) { dest[j++] = (byte) ((data[i] >>> 2) & 077); if (i < offset + length - 1) { dest[j++] = (byte) ((data[i+1] >>> 4) & 017 | (data[i] << 4) & 077); dest[j++] = (byte) ((data[i+1] << 2) & 077); } else dest[j++] = (byte) ((data[i] << 4) & 077); } // Now, map those onto base 64 printable ASCII. for (i = 0; i data.length) throw new IndexOutOfBoundsException("Can't decode beyond right edge of array"); // Ignore any padding at the end. int tail = offset + length - 1; while (tail >= offset && data[tail] == '=') --tail; byte dest[] = new byte[tail + offset + 1 - length/4]; // First, convert from base-64 ascii to 6 bit bytes. for (int i = offset; i < offset+length; i++) { if (data[i] == '=') data[i] = 0; else if (data[i] == '/') data[i] = 63; else if (data[i] == '+') data[i] = 62; else if (data[i] >= '0' && data[i] <= '9') data[i] = (byte)(data[i] - ('0' - 52)); else if (data[i] >= 'a' && data[i] <= 'z') data[i] = (byte)(data[i] - ('a' - 26)); else if (data[i] >= 'A' && data[i] <= 'Z') data[i] = (byte)(data[i] - 'A'); } // Map those from 4 6-bit byte groups onto 3 8-bit byte groups. int i, j; for (i = 0 + offset, j = 0; j < dest.length - 2; i += 4, j += 3) { dest[j] = (byte) (((data[i] << 2) & 255) | ((data[i+1] >>> 4) & 003)); dest[j+1] = (byte) (((data[i+1] << 4) & 255) | ((data[i+2] >>> 2) & 017)); dest[j+2] = (byte) (((data[i+2] << 6) & 255) | (data[i+3] & 077)); } // And get the leftover ... if (j < dest.length) dest[j] = (byte) (((data[i] << 2) & 255) | ((data[i+1] >>> 4) & 003)); if (++j < dest.length) dest[j] = (byte) (((data[i+1] << 4) & 255) | ((data[i+2] >>> 2) & 017)); // That's it. return dest; } /** This class provides namespace for utility methods and shouldn't be instantiated. */ private Base64() { throw new IllegalStateException(getClass().getName() + " should not be instantiated"); } /** Command-line runner that encodes or decodes. * * @param argv Command-line arguments. */ public static void main(String[] argv) throws Exception { if (argv.length < 1 || argv.length > 2) { System.err.println("Usage: encode|decode [file]"); System.exit(1); } boolean encode = true; if ("encode".equals(argv[0])) encode = true; else if ("decode".equals(argv[0])) encode = false; else { System.err.println("Specify either \"encode\" or \"decode\""); System.exit(1); } InputStream source = argv.length == 2? new BufferedInputStream(new FileInputStream(argv[1])) : System.in; InputStream in; OutputStream out; if (encode) { in = source; out = new Base64EncodingOutputStream(System.out); } else { in = new Base64DecodingInputStream(source); out = System.out; } byte[] buf = new byte[512]; int numRead; while ((numRead = in.read(buf)) != -1) out.write(buf, 0, numRead); in.close(); out.close(); System.exit(0); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy