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

com.hfg.util.Base32 Maven / Gradle / Ivy

There is a newer version: 20240423
Show newest version
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);
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy