/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xwiki.social.legacy.crypto.internal; import java.io.UnsupportedEncodingException; import org.bouncycastle.util.encoders.Base64; /** * Utility class for various string conversions, such as base64 encoding and decoding and conversion * to byte array. Supports conversion of strings containing base64 encoded data. The conversion uses * UTF-8 because it is always available and base64 alphabet is a subset of UTF-8. * * @version $Id: 40a2303a281db903f6aa2b98faec495ac7588dc2 $ * @since 2.5M1 */ public final class Convert { /** Charset used for String <-> byte[] conversion. */ private static final String CHARSET = "UTF-8"; /** Default line length for {@link #toChunkedBase64String(byte[])}. */ private static final int DEFAULT_LINE_LENGTH = 64; /** New line separator. */ private static final String NEWLINE = System.getProperty("line.separator", "\n"); /** * Private default constructor to prevent instantiation. */ private Convert() { // this class is not supposed to be instantiated } /** * Encode given data and return the base64 encoded result as string (no line breaks). * * @param data the data to encode * @return base64 encoded data */ public static String toBase64String(byte[] data) { try { return new String(toBase64(data), CHARSET); } catch (UnsupportedEncodingException exception) { // cannot happen throw new RuntimeException(exception); } } /** * Encode given data and return the base64 encoded result as string, chunking it into several lines * of the default length (64). * * @param data the data to encode * @return base64 encoded data */ public static String toChunkedBase64String(byte[] data) { return toChunkedBase64String(data, DEFAULT_LINE_LENGTH); } /** * Encode given data and return the base64 encoded result as string, chunking it into several lines * of the given length. * * @param data the data to encode * @param lineLength maximal line length * @return base64 encoded data */ public static String toChunkedBase64String(byte[] data, int lineLength) { StringBuilder result = new StringBuilder(); String encoded = toBase64String(data); int begin = 0; int end = lineLength; while (end < encoded.length()) { result.append(encoded.substring(begin, end)); result.append(NEWLINE); begin = end; end += lineLength; } result.append(encoded.substring(begin)); result.append(NEWLINE); return result.toString(); } /** * Encode given data and return the base64 encoded result as a byte array. * * @param data the data to encode * @return base64 encoded data array */ public static byte[] toBase64(byte[] data) { if (data == null) { return new byte[0]; } return Base64.encode(data); } /** * Decode the base64 encoded data represented as string. * Ignore anything before beginningMarker or after endMarker. * * @param withBase64EncodedContent string containing base64 encoded data. * @param beginningMarker anything in the string which is not after this will be ignored. * @param endMarker anything in the string which is not before this will be ignored. * @return the decoded data array */ public static byte[] fromBase64String(final String withBase64EncodedContent, final String beginningMarker, final String endMarker) { return Convert.fromBase64(Convert.stringToBytes(withBase64EncodedContent, beginningMarker, endMarker)); } /** * Decode the base64 encoded data represented as string. * * @param base64Encoded base64 encoded data string * @return the decoded data array */ public static byte[] fromBase64String(String base64Encoded) { return fromBase64(stringToBytes(base64Encoded)); } /** * Decode the base64 encoded data array. * * @param base64Encoded base64 encoded data * @return the decoded data array */ public static byte[] fromBase64(byte[] base64Encoded) { if (base64Encoded == null || base64Encoded.length == 0) { return new byte[0]; } return Base64.decode(base64Encoded); } /** * Get substring between beginningMarker and endMarker. * * @param input string to get content from. * @param beginningMarker anything in the string which is not after this will be ignored. * @param endMarker anything in the string which is not before this will be ignored. * @return part of input between beginningMarker and endMarker. */ public static String getContentBetween(final String input, final String beginningMarker, final String endMarker) { if (input == null) { throw new IllegalArgumentException("Given string is null"); } int beginIndex = input.indexOf(beginningMarker); if (beginIndex < 0) { throw new IllegalArgumentException("No beginning marker found in string\nExpecting: " + beginningMarker); } final int endIndex = input.indexOf(endMarker, beginIndex); if (endIndex < 0) { throw new IllegalArgumentException("No end marker found in string\nExpecting: " + endMarker); } beginIndex += beginningMarker.length(); return input.substring(beginIndex, endIndex); } /** * Convert string to byte array using the same encoding as for base64 conversion. * Ignore anything before beginningMarker or after endMarker. * * @param withBase64EncodedContent string containing base64 encoded data. * @param beginningMarker anything in the string which is not after this will be ignored. * @param endMarker anything in the string which is not before this will be ignored. * @return byte array containing the characters from the string (still in Base64 format) */ public static byte[] stringToBytes(final String withBase64EncodedContent, final String beginningMarker, final String endMarker) { return Convert.stringToBytes(Convert.getContentBetween(withBase64EncodedContent, beginningMarker, endMarker)); } /** * Convert string to byte array using the same encoding as for base64 conversion. * * @param string the string to convert * @return byte array containing the characters from the string */ public static byte[] stringToBytes(String string) { if (string == null) { return new byte[0]; } try { return string.getBytes(CHARSET); } catch (UnsupportedEncodingException exception) { // cannot happen throw new RuntimeException(exception); } } /** * Convert byte array into a string using UTF-8 encoding. * * @param bytes to make into a string * @return new String from the given bytes. */ public static String bytesToString(byte[] bytes) { if (bytes == null) { return ""; } try { return new String(bytes, CHARSET); } catch (UnsupportedEncodingException exception) { // cannot happen throw new RuntimeException(exception); } } /** * @return a newline string, dependent on platform. */ public static String getNewline() { return Convert.NEWLINE; } }