TL; DR: What is the edge that I am missing, or is there an error in my algorithm for converting a Base64 string to a hexadecimal string?
I recently decided to try Matasano's Answers to Criticism , but for some reason I decided to try the first call without using the Hex and Base64 string conversion library.
I managed to convert Hex to Base64, but as you can see from the output, there is a slight anomaly when I try to convert Base64 back to Hex (for example, compare the last four Base64 values to Hex output).
Hex To Base64:
Must Seal: SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t Actually Seal: SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGcb2g2cb2hy
Base64 to Hex:
If the print: 49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f 6f 6d
fact Prints: 49276d206b696c6c696e6720796e717220627261696e206c696b65206120706e69732e6e6f3573206c717328726f 2e 6d
I used https://conv.darkbyte.ru/ to check some of my values, and if the code on this site is correct, it seems my problem is with the Base10 representation from Base64, and not Base10 in Hex:
Decimal equivalent
:
73, 39, 109, 32, 107, 105, 108, 108, 105, 110, 103, 32, 121, 110, 113, 114, 32, 98, 114, 97, 105, 110, 32, 108, 105, 107, 101, 32, 97, 32, 112, 110, 105, 115, 46, 110, 111, 53, 115, 32, 108, 113, 115, 40, 114, 111, 46, 109
:
73, 39, 109, 32, 107, 105, 108, 108, 105, 110, 103, 32, 121, 111, 117, 114, 32, 98, 114, 97, 105, 110, 32, 108, 105, 107, 101, 32, 97, 32, 112, 111, 105, 115, 111, 110, 111, 117, 115, 32, 109, 117, 115, 104, 114, 111, 111, 109
, 40-60 100-120, , . , - , , , .
:
private static final Character[] base64Order = new Character[] { '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', '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',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', };
private static final Character[] hexOrder = new Character[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
'b', 'c', 'd', 'e', 'f' };
public static String base64ToHex(String base64) throws Exception {
if (base64.length() % 4 != 0 || base64.contains("[^a-zA-Z0-9\\+/]"))
throw new Exception("InputNotBase64");
else {
int charValue = 0;
int index = 0;
String hex = "";
BitSet bits = new BitSet();
for (int i = 0; i < base64.length(); i++) {
charValue = base64.charAt(i);
if (charValue > 64 && charValue < 91)
charValue -= 65;
if (charValue > 96 && charValue < 123)
charValue -= 71;
charValue = Integer.reverse(charValue << 24) & 0xff;
charValue >>= 2;
while (charValue != 0L) {
if (charValue % 2 != 0) {
bits.set(index);
}
index++;
charValue >>= 1;
}
while (index % 6 != 0) {
index++;
}
}
String temp;
int remainder;
for (int i = 0; i < index; i++) {
charValue = (charValue | (bits.get(i) ? 1 : 0));
if ((i + 1) % 8 == 0) {
temp = "";
while (charValue != 0L) {
remainder = charValue % 16;
temp = hexOrder[remainder] + temp;
charValue /= 16;
}
hex += temp;
}
charValue <<= 1;
}
return hex;
}
}