Java conversion of base 16 to base 64 I wrote a solution in Java to solve the problem here. I use BigInteger to convert first from base 16 to base 10, then base 10 to base 64.  

This seems quite inefficient to me, and I would have no idea how to do this if I couldn't use BigInteger.  I'm sure there's a nice and clever way to do this using a lot more bit manipulation.

import java.math.BigInteger;


public class Base64{

    //according to RFC 4648 and RFC 2045
    public final static char[] base64alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
    public final static char base64pad = '='; //unused

    public static void main(String[] args){

        String test = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";
        System.out.println( base16to64( test ) );
    }

    /**Return the base 64 value of an input base 16 string.
     */
    public static String base16to64(String hex){
        BigInteger value = base16to10(hex); //base 10 value

        // --- convert base 10 to 64 ---
        int digits = 1; // # digits in base 64 we'll need
        while( value.compareTo(new BigInteger("64").pow(digits)) != -1 ){ //while the decimal value &gt;= 64^i
            digits++;
        }

        String ret = "";
        for(int i = digits - 1; i &gt;= 0; i--){ //start at most significant digit

            //this digit must be an A (represents 0)
            if( value.subtract(new BigInteger("64").pow(i)).compareTo(BigInteger.ZERO) == -1){
                ret += "A";
            }
            else{
                for(int d = 63; d &gt;= 1; d--){
                    //digit found: [ value - (64^i)*d &gt;= 0 ]  with d the greatest possible
                    if( value.subtract(new BigInteger("64").pow(i).multiply(
                            new BigInteger(Integer.toString(d)))).compareTo(BigInteger.ZERO) != -1){
                        value = value.subtract(new BigInteger("64").pow(i).multiply( new BigInteger(Integer.toString(d))));
                        ret += base64alphabet[d];
                        break;
                    }
                }
            }//end else
        }

        return ret;
    }//end base16to64()

    /**Return the BigInteger decimal value of an input hexadecimal string.
     */
    public static BigInteger base16to10(String hex){
        hex = hex.toLowerCase();

        //hex is 0-9 then a-f
        BigInteger value = BigInteger.ZERO; //base 10 value
        for(int i = 0; i &lt; hex.length(); i++){ //moving from most significant digit towards 16^0

            int digit = (int) hex.charAt(i);
            //if the hex digit is 0-9
            if( '0' &lt;= hex.charAt(i) &amp;&amp; hex.charAt(i) &lt;= '9')
                digit = digit - '0'; 
            //else the hex digit is a-f
            else
                digit = digit - 'a' + 10; 

            BigInteger temp = new BigInteger("" + digit); // digit as BigInt
            temp = temp.multiply( new BigInteger("16").pow( hex.length() - 1 - i) ); // digit * 16^index
            value = value.add(temp);
        }

        return value;
    }//end base16to10()
}
You are working too hard. Java has a Base64 class that does most of the work for you, all you need to do is combine it and the constructor for BigInteger, and you are done.

public static String base16to64(String hex){
    return Base64.getEncoder().encodeToString(new BigInteger(hex, 16).toByteArray());
}


For the linked example input:


  49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d


We get the correct output:


  SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t




If you wanted to implement the base 64 conversion yourself, note that you are still doing too much work. Your base16to10 function could be replaced with

BigInteger value = new BigInteger(hex, 16);


One function completely cut out.



However, if you don't want to use BigInteger at all (this is generally a bad idea, but for programming practice, you might want to), notice that log(64)/log(16) == 1.5. Thus, for every 1.5 hex digits, we can obtain 1 base 64 digits.

So take the last 2 hex digits of the hex string: 6d. In binary, this is 01101101. We only need to consider 101101, which is 45. So we take the 45th element of the base 64 alphabet: t. That's the last digit of the base 64 string. Now just shift the hex string over by 6 bits, and repeat (note, shifting by 6 bits won't be clean, so it's probably easier to instead process 3 hex digits to 2 base 64 digits, and take off the last two elements of the hex string).

But noticing the "Cryptopals Rule":


  Always operate on raw bytes, never on encoded strings. Only use hex and base64 for pretty-printing.


You should probably parse the hex string into a byte[] or ArrayList&lt;Byte&gt; before working on it. Honestly, I think this is way easier to do using BigInteger.