com.hfg.util.Base32 Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com_hfg Show documentation
Show all versions of com_hfg Show documentation
com.hfg xml, html, svg, and bioinformatics utility library
package com.hfg.util;
import java.util.HashMap;
import java.util.Map;
//------------------------------------------------------------------------------
/**
* A basic base32 encoder / decoder.
*
* @author J. Alex Taylor, hairyfatguy.com
*/
//------------------------------------------------------------------------------
// com.hfg XML/HTML Coding Library
//
// This library 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 library 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 library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
// [email protected]
//------------------------------------------------------------------------------
public class Base32
{
// The 32 character dictionary used for encoding
private static final byte[] ENCODING_ALPHABET =
{ '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', '2', '3', '4', '5',
'6', '7' };
private static final Map DECODING_MAP = new HashMap<>(32);
static
{
DECODING_MAP.put('A', 0);
DECODING_MAP.put('B', 1);
DECODING_MAP.put('C', 2);
DECODING_MAP.put('D', 3);
DECODING_MAP.put('E', 4);
DECODING_MAP.put('F', 5);
DECODING_MAP.put('G', 6);
DECODING_MAP.put('H', 7);
DECODING_MAP.put('I', 8);
DECODING_MAP.put('J', 9);
DECODING_MAP.put('K', 10);
DECODING_MAP.put('L', 11);
DECODING_MAP.put('M', 12);
DECODING_MAP.put('N', 13);
DECODING_MAP.put('O', 14);
DECODING_MAP.put('P', 15);
DECODING_MAP.put('Q', 16);
DECODING_MAP.put('R', 17);
DECODING_MAP.put('S', 18);
DECODING_MAP.put('T', 19);
DECODING_MAP.put('U', 20);
DECODING_MAP.put('V', 21);
DECODING_MAP.put('W', 22);
DECODING_MAP.put('X', 23);
DECODING_MAP.put('Y', 24);
DECODING_MAP.put('Z', 25);
DECODING_MAP.put('2', 26);
DECODING_MAP.put('3', 27);
DECODING_MAP.put('4', 28);
DECODING_MAP.put('5', 29);
DECODING_MAP.put('6', 30);
DECODING_MAP.put('7', 31);
}
//--------------------------------------------------------------------------
/**
* Encodes an array of bytes as a Base32 string.
* @param inByteArray the bytes to be encoded
* @return a base32-encoded string
*/
public static String encode(byte[] inByteArray)
{
StringBuilder base32Buffer = new StringBuilder((int) Math.ceil((inByteArray.length * 8f) / 5));
byte[] fiveBitBytes = ByteUtil.marshallBytes(inByteArray, 8, 5);
for (byte fiveBitByte : fiveBitBytes)
{
base32Buffer.append((char) ENCODING_ALPHABET[fiveBitByte]);
}
// Add padding to a number of bytes divisible by 8
int danglingBytes = base32Buffer.length() % 8;
if (danglingBytes > 0)
{
base32Buffer.append(StringUtil.polyChar('=', 8 - danglingBytes));
}
return base32Buffer.toString();
}
//--------------------------------------------------------------------------
/**
* Decodes a Base32 string.
* @param inEncodedValue a base32-encoded string
* @return the un-encoded bytes
*/
public static byte[] decode(String inEncodedValue)
{
// Trim any trailing '=' used for padding
String encodedValueWithoutPadding = inEncodedValue.replaceAll("=+$", "");
byte[] fiveBitBytes = new byte[encodedValueWithoutPadding.length()];
for (int i = 0; i < encodedValueWithoutPadding.length(); i++)
{
char theChar = encodedValueWithoutPadding.charAt(i);
fiveBitBytes[i] = (byte) DECODING_MAP.get(theChar).intValue();
}
// Convert the 5-bit bytes back into 8-bit bytes
return ByteUtil.marshallBytes(fiveBitBytes, 5, 8);
}
}