I was going through these crypopals challenges, where I decided to do some of these problems in a language that was familiar to me (C++). The first challenge dealt with converting a hex string to base64. This type of conversion is used in encode all types of data such as text, images, etc. So, let’s dive into the problem. The problem states that the input is a string which represents an hexadecimal number. The output of your function/program should be a string which is a representation of the input hexadecimal number in base64. My solution to this problem would be to convert the input hexadecimal first into binary and then convert this binary in groups of 6(remember that base64 is represented by 6 binary digits, i.e it’s range is from \(0\) to \(2^6 – 1\), with each number representing a character ). Note that no padding is done in this implementation.
#include <bitset>
#include <cassert>
#include <iostream>
#include <string>
std::string convert_hex_base64(const std::string hex_string)
{
static const std::string base64_lookup = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
std::string binary_string, output_string;
auto hex_char_to_binary = [](const char c) {
int hex_i = std::stoi(std::string(1, c), nullptr, 16);
std::bitset<4> hex_val(hex_i);
return hex_val.to_string();
};
// convert hex string to binary
for (const char c : hex_string) {
binary_string.append(hex_char_to_binary(c));
}
//convert binary string to base64
for (std::string::size_type i = 0; i < binary_string.size(); i = i + 6) {
int idx = std::stoi(binary_string.substr(i, 6), nullptr, 2);
output_string.push_back(base64_lookup.at(idx));
}
return output_string;
}
int main()
{
assert(convert_hex_base64("49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d") == "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t");
assert(convert_hex_base64("000000") == "AAAA");
assert(convert_hex_base64("010008") == "AQAI");
}