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

com.pslib.jtool.security.base64.NewBase64 Maven / Gradle / Ivy

/*
 * Java Base64 - A pure Java library for reading and writing Base64
 *               encoded streams.
 * 
 * Copyright (C) 2007-2009 Carlo Pelliccia (www.sauronsoftware.it)
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version
 * 2.1, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License version 2.1 along with this program.
 * If not, see .
 */
package com.pslib.jtool.security.base64;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

/**
 * 

* Base64 encoding and decoding utility methods, both for binary and textual informations. *

* * @author Carlo Pelliccia * @since 1.1 * @version 1.3 */ public class NewBase64 { public static final String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._"; public static final char pad = '-'; /** *

* Encodes a string. *

*

* Before the string is encoded in Base64, it is converted in a binary sequence using the system default charset. *

* * @param str * The source string. * @return The encoded string. * @throws RuntimeException * If an unexpected error occurs. */ public static String encode(String str) throws RuntimeException { byte[] bytes = str.getBytes(); byte[] encoded = encode(bytes); try { return new String(encoded, "ASCII"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("ASCII is not supported!", e); } } /** *

* Encodes a string. *

*

* Before the string is encoded in Base64, it is converted in a binary sequence using the supplied charset. *

* * @param str * The source string * @param charset * The charset name. * @return The encoded string. * @throws RuntimeException * If an unexpected error occurs. * @since 1.2 */ public static String encode(String str, String charset) throws RuntimeException { byte[] bytes; try { bytes = str.getBytes(charset); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Unsupported charset: " + charset, e); } byte[] encoded = encode(bytes); try { return new String(encoded, "ASCII"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("ASCII is not supported!", e); } } /** *

* Decodes the supplied string. *

*

* The supplied string is decoded into a binary sequence, and then the sequence is encoded with the system default charset and returned. *

* * @param str * The encoded string. * @return The decoded string. * @throws RuntimeException * If an unexpected error occurs. */ public static String decode(String str) throws RuntimeException { byte[] bytes; try { bytes = str.getBytes("ASCII"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("ASCII is not supported!", e); } byte[] decoded = decode(bytes); return new String(decoded); } /** *

* Decodes the supplied string. *

*

* The supplied string is decoded into a binary sequence, and then the sequence is encoded with the supplied charset and returned. *

* * @param str * The encoded string. * @param charset * The charset name. * @return The decoded string. * @throws RuntimeException * If an unexpected error occurs. * @since 1.2 */ public static String decode(String str, String charset) throws RuntimeException { byte[] bytes; try { bytes = str.getBytes("ASCII"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("ASCII is not supported!", e); } byte[] decoded = decode(bytes); try { return new String(decoded, charset); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Unsupported charset: " + charset, e); } } /** *

* Encodes a binary sequence. *

*

* If data are large, i.e. if you are working with large binary files, consider to use a {@link Base64OutputStream} instead of loading too much data in memory. *

* * @param bytes * The source sequence. * @return The encoded sequence. * @throws RuntimeException * If an unexpected error occurs. * @since 1.2 */ public static byte[] encode(byte[] bytes) throws RuntimeException { return encode(bytes, 0); } /** *

* Encodes a binary sequence, wrapping every encoded line every wrapAt characters. A wrapAt value less than 1 disables wrapping. *

*

* If data are large, i.e. if you are working with large binary files, consider to use a {@link Base64OutputStream} instead of loading too much data in memory. *

* * @param bytes * The source sequence. * @param wrapAt * The max line length for encoded data. If less than 1 no wrap is applied. * @return The encoded sequence. * @throws RuntimeException * If an unexpected error occurs. * @since 1.2 */ public static byte[] encode(byte[] bytes, int wrapAt) throws RuntimeException { ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { encode(inputStream, outputStream, wrapAt); } catch (IOException e) { throw new RuntimeException("Unexpected I/O error", e); } finally { try { inputStream.close(); } catch (Throwable t) { ; } try { outputStream.close(); } catch (Throwable t) { ; } } return outputStream.toByteArray(); } /** *

* Decodes a binary sequence. *

*

* If data are large, i.e. if you are working with large binary files, consider to use a {@link Base64InputStream} instead of loading too much data in memory. *

* * @param bytes * The encoded sequence. * @return The decoded sequence. * @throws RuntimeException * If an unexpected error occurs. * @since 1.2 */ public static byte[] decode(byte[] bytes) throws RuntimeException { ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); try { decode(inputStream, outputStream); } catch (IOException e) { throw new RuntimeException("Unexpected I/O error", e); } finally { try { inputStream.close(); } catch (Throwable t) { ; } try { outputStream.close(); } catch (Throwable t) { ; } } return outputStream.toByteArray(); } /** *

* Encodes data from the given input stream and writes them in the given output stream. *

*

* The supplied input stream is read until its end is reached, but it's not closed by this method. *

*

* The supplied output stream is nor flushed neither closed by this method. *

* * @param inputStream * The input stream. * @param outputStream * The output stream. * @throws IOException * If an I/O error occurs. */ public static void encode(InputStream inputStream, OutputStream outputStream) throws IOException { encode(inputStream, outputStream, 0); } /** *

* Encodes data from the given input stream and writes them in the given output stream, wrapping every encoded line every wrapAt characters. A wrapAt value less than 1 disables wrapping. *

*

* The supplied input stream is read until its end is reached, but it's not closed by this method. *

*

* The supplied output stream is nor flushed neither closed by this method. *

* * @param inputStream * The input stream from which clear data are read. * @param outputStream * The output stream in which encoded data are written. * @param wrapAt * The max line length for encoded data. If less than 1 no wrap is applied. * @throws IOException * If an I/O error occurs. */ public static void encode(InputStream inputStream, OutputStream outputStream, int wrapAt) throws IOException { NBase64OutputStream aux = new NBase64OutputStream(outputStream, wrapAt); copy(inputStream, aux); aux.commit(); } /** *

* Decodes data from the given input stream and writes them in the given output stream. *

*

* The supplied input stream is read until its end is reached, but it's not closed by this method. *

*

* The supplied output stream is nor flushed neither closed by this method. *

* * @param inputStream * The input stream from which encoded data are read. * @param outputStream * The output stream in which decoded data are written. * @throws IOException * If an I/O error occurs. */ public static void decode(InputStream inputStream, OutputStream outputStream) throws IOException { copy(new NBase64InputStream(inputStream), outputStream); } /** *

* Encodes data from the given source file contents and writes them in the given target file, wrapping every encoded line every wrapAt characters. A wrapAt value less than 1 disables wrapping. *

* * @param source * The source file, from which decoded data are read. * @param target * The target file, in which encoded data are written. * @param wrapAt * The max line length for encoded data. If less than 1 no wrap is applied. * @throws IOException * If an I/O error occurs. * @since 1.3 */ public static void encode(File source, File target, int wrapAt) throws IOException { InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = new FileInputStream(source); outputStream = new FileOutputStream(target); NewBase64.encode(inputStream, outputStream, wrapAt); } finally { if (outputStream != null) { try { outputStream.close(); } catch (Throwable t) { ; } } if (inputStream != null) { try { inputStream.close(); } catch (Throwable t) { ; } } } } /** *

* Encodes data from the given source file contents and writes them in the given target file. *

* * @param source * The source file, from which decoded data are read. * @param target * The target file, in which encoded data are written. * @throws IOException * If an I/O error occurs. * @since 1.3 */ public static void encode(File source, File target) throws IOException { InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = new FileInputStream(source); outputStream = new FileOutputStream(target); NewBase64.encode(inputStream, outputStream); } finally { if (outputStream != null) { try { outputStream.close(); } catch (Throwable t) { ; } } if (inputStream != null) { try { inputStream.close(); } catch (Throwable t) { ; } } } } /** *

* Decodes data from the given source file contents and writes them in the given target file. *

* * @param source * The source file, from which encoded data are read. * @param target * The target file, in which decoded data are written. * @throws IOException * If an I/O error occurs. * @since 1.3 */ public static void decode(File source, File target) throws IOException { InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = new FileInputStream(source); outputStream = new FileOutputStream(target); decode(inputStream, outputStream); } finally { if (outputStream != null) { try { outputStream.close(); } catch (Throwable t) { ; } } if (inputStream != null) { try { inputStream.close(); } catch (Throwable t) { ; } } } } /** * Copies data from a stream to another. * * @param inputStream * The input stream. * @param outputStream * The output stream. * @throws IOException * If a unexpected I/O error occurs. */ private static void copy(InputStream inputStream, OutputStream outputStream) throws IOException { // 1KB buffer byte[] b = new byte[1024]; int len; while ((len = inputStream.read(b)) != -1) { outputStream.write(b, 0, len); } } } /** *

* A base64 encoding input stream. *

* *

* A Base64InputStream reads from an underlying stream which is supposed to be a base64 encoded stream. Base64InputStream decodes the data read from the underlying stream and returns the decoded bytes * to the caller. *

* * @author Carlo Pelliccia */ class NBase64InputStream extends InputStream { /** * The underlying stream. */ private InputStream inputStream; /** * The buffer. */ private int[] buffer; /** * A counter for values in the buffer. */ private int bufferCounter = 0; /** * End-of-stream flag. */ private boolean eof = false; /** *

* It builds a base64 decoding input stream. *

* * @param inputStream * The underlying stream, from which the encoded data is read. */ public NBase64InputStream(InputStream inputStream) { this.inputStream = inputStream; } public int read() throws IOException { if (buffer == null || bufferCounter == buffer.length) { if (eof) { return -1; } acquire(); if (buffer.length == 0) { buffer = null; return -1; } bufferCounter = 0; } return buffer[bufferCounter++]; } /** * Reads from the underlying stream, decodes the data and puts the decoded bytes into the buffer. */ private void acquire() throws IOException { char[] four = new char[4]; int i = 0; do { int b = inputStream.read(); if (b == -1) { if (i != 0) { throw new IOException("Bad base64 stream"); } else { buffer = new int[0]; eof = true; return; } } char c = (char) b; if (NewBase64.chars.indexOf(c) != -1 || c == NewBase64.pad) { four[i++] = c; } else if (c != '\r' && c != '\n') { throw new IOException("Bad base64 stream"); } } while (i < 4); boolean padded = false; for (i = 0; i < 4; i++) { if (four[i] != NewBase64.pad) { if (padded) { throw new IOException("Bad base64 stream"); } } else { if (!padded) { padded = true; } } } int l; if (four[3] == NewBase64.pad) { if (inputStream.read() != -1) { throw new IOException("Bad base64 stream"); } eof = true; if (four[2] == NewBase64.pad) { l = 1; } else { l = 2; } } else { l = 3; } int aux = 0; for (i = 0; i < 4; i++) { if (four[i] != NewBase64.pad) { aux = aux | (NewBase64.chars.indexOf(four[i]) << (6 * (3 - i))); } } buffer = new int[l]; for (i = 0; i < l; i++) { buffer[i] = (aux >>> (8 * (2 - i))) & 0xFF; } } public void close() throws IOException { inputStream.close(); } } /** *

* A base64 decoding output stream. *

* *

* It encodes in base64 everything passed to the stream, and it puts the encoded data into the underlying stream. *

* * @author Carlo Pelliccia */ class NBase64OutputStream extends OutputStream { /** * The underlying stream. */ private OutputStream outputStream = null; /** * A value buffer. */ private int buffer = 0; /** * How many bytes are currently in the value buffer? */ private int bytecounter = 0; /** * A counter for the current line length. */ private int linecounter = 0; /** * The requested line length. */ private int linelength = 0; /** *

* It builds a base64 encoding output stream writing the encoded data in the given underlying stream. *

* *

* The encoded data is wrapped to a new line (with a CRLF sequence) every 76 bytes sent to the underlying stream. *

* * @param outputStream * The underlying stream. */ public NBase64OutputStream(OutputStream outputStream) { this(outputStream, 76); } /** *

* It builds a base64 encoding output stream writing the encoded data in the given underlying stream. *

* *

* The encoded data is wrapped to a new line (with a CRLF sequence) every wrapAt bytes sent to the underlying stream. If the wrapAt supplied value is less than 1 the encoded data will not be * wrapped. *

* * @param outputStream * The underlying stream. * @param wrapAt * The max line length for encoded data. If less than 1 no wrap is applied. */ public NBase64OutputStream(OutputStream outputStream, int wrapAt) { this.outputStream = outputStream; this.linelength = wrapAt; } public void write(int b) throws IOException { int value = (b & 0xFF) << (16 - (bytecounter * 8)); buffer = buffer | value; bytecounter++; if (bytecounter == 3) { commit(); } } public void close() throws IOException { commit(); outputStream.close(); } /** *

* It commits 4 bytes to the underlying stream. *

*/ protected void commit() throws IOException { if (bytecounter > 0) { if (linelength > 0 && linecounter == linelength) { outputStream.write("\r\n".getBytes()); linecounter = 0; } char b1 = NewBase64.chars.charAt((buffer << 8) >>> 26); char b2 = NewBase64.chars.charAt((buffer << 14) >>> 26); char b3 = (bytecounter < 2) ? NewBase64.pad : NewBase64.chars.charAt((buffer << 20) >>> 26); char b4 = (bytecounter < 3) ? NewBase64.pad : NewBase64.chars.charAt((buffer << 26) >>> 26); outputStream.write(b1); outputStream.write(b2); outputStream.write(b3); outputStream.write(b4); linecounter += 4; bytecounter = 0; buffer = 0; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy