2

I am working on the Matasano CryptoChallenge, and the first one is to create a Hex to Base 64 converter. I honestly don't know how to continue from here. My code:

public class HexToBase64 {

public static void main(String[] args) {
//        String hex  = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";
    String hex = "DA65A";
    convertHexTo64(hex);
}

public static String convertHexTo64(String hex) {
    //convert each letter in the hex string to a 4-digit binary string to create a binary representation of the hex string
    StringBuilder binary = new StringBuilder();
    for (int i = 0; i < hex.length(); i++) {
        int dec = Integer.parseInt(hex.charAt(i) + "", 16);
        StringBuilder bin = new StringBuilder(Integer.toBinaryString(dec));
        while(bin.length() < 4){
            bin.insert(0,'0');
        }
        binary.append(bin);
    }
    //now take 6 bits at a time and convert to a single b64 digit to create the final b64 representation
    StringBuilder b64 = new StringBuilder();
    for (int i = 0; i < binary.length(); i++) {
        String temp = binary.substring(i, i+5);
        int dec = Integer.parseInt(temp, 10);
        //convert dec to b64 with the lookup table here then append to b64
    }

    return b64.toString();
}
}

So after I separate the binary 6 bits at a time and convert to decimal, how do I map the decimal number to the corresponding digit in b64? Would a Hashmap/Hashtable implementation be efficient?

Also, this algorithm displays how I would go about doing the conversion by hand. Is there a better way of doing this? I am looking for a way to convert that will take a reasonable amount of time, so time, and implicitly efficiency, is relevant.

Thank you for your time

EDIT: And the page also mentions that "Always operate on raw bytes, never on encoded strings. Only use hex and base64 for pretty-printing." What does that mean exactly?

6
  • 2
    Do you want to do it manually or want to use 3rd party library? Commented Dec 15, 2014 at 22:10
  • I would prefer manually for the purpose of understanding the inner workings Commented Dec 15, 2014 at 22:11
  • 1
    What that means is that you have to convert your hexadecimal string to a byte[], so that a string like 8DAB11 is converted to { (byte)0x8D, (byte)0xAB, (byte)0x11 } - or to a similar collection of bytes. No StringBuilders. Commented Dec 15, 2014 at 22:11
  • I don't mind, I would just like to understand what is going on. I saw many implementations online with byte arrays, but I don't get whats going on Commented Dec 15, 2014 at 22:15
  • 1
    So you'll need to scratch your program and start fresh. General guidelines: Write methods to convert hex to byte array, byte array to hex, and byte array to string (each byte to a char). Then write a method that converts a byte array to another byte array using the base64 algorithm. Manipulate the bits using bitwise operations like &, |, <<, >> etc. Commented Dec 15, 2014 at 22:18

3 Answers 3

6

Extracted from this Stack Overflow post, which references Apache Commons Codec

byte[] decodedHex = Hex.decodeHex(hex);
byte[] encodedHexB64 = Base64.codeBase64(decodedHex);
Sign up to request clarification or add additional context in comments.

3 Comments

You forget to mention that Hex is from Commons Codec
Thank you for that. But can you explain what the code does? And why does it use byte arrays?
@yazan here's the related javadoc's that explain what they do and what they return: commons.apache.org/proper/commons-codec/apidocs/org/apache/… -- and -- commons.apache.org/proper/commons-codec/apidocs/org/apache/…
2

With Java 17+ this can be done without additional dependencies:

import java.util.Base64;
import java.util.HexFormat;

String inputHex = "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08";

byte[] hexBytes = HexFormat.of().parseHex(inputHex);
byte[] base64Bytes = Base64.getEncoder().encode(hexBytes);

Or, optionally, getting it as String directly:

String base64String = Base64.getEncoder().encodeToString(hexBytes);

References:

Comments

1
String hex = "00bc9d2a05ef06c79a6e972f8a36737e";
byte[] decodedHex = org.apache.commons.codec.binary.Hex.decodeHex(hex.toCharArray());
String result = Base64.encodeBase64String(decodedHex);
System.out.println("==> " + result);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.