Convert strings between hex format and binary format
If you want a concise solution in plain c++11. Here you go:
string hextobin(const string &s){
string out;
for(auto i: s){
uint8_t n;
if(i <= '9' and i >= '0')
n = i - '0';
else
n = 10 + i - 'A';
for(int8_t j = 3; j >= 0; --j)
out.push_back((n & (1<<j))? '1':'0');
}
return out;
}
string bintohex(const string &s){
string out;
for(uint i = 0; i < s.size(); i += 4){
int8_t n = 0;
for(uint j = i; j < i + 4; ++j){
n <<= 1;
if(s[j] == '1')
n |= 1;
}
if(n<=9)
out.push_back('0' + n);
else
out.push_back('A' + n - 10);
}
return out;
}
This would work for any length of string with no padding required. Should be pretty fast since there's no long switch cases and bit operations are fast.
Example usage:
string s = "FF11";
string b = hextobin(s);
cout << b << endl; // prints 1111111100010001
string h = bintohex(b);
cout << h << endl; // prints FF11
You can use a combination of std::stringstream
, std::hex
and std::bitset
to convert between hex and binary in C++03.
Here's an example:
#include <iostream>
#include <sstream>
#include <bitset>
#include <string>
using namespace std;
int main()
{
string s = "0xA";
stringstream ss;
ss << hex << s;
unsigned n;
ss >> n;
bitset<32> b(n);
// outputs "00000000000000000000000000001010"
cout << b.to_string() << endl;
}
EDIT:
About the refined question, here's a code example about converting between hex strings and binary strings (you can refactor with a helper function for the hex char<>bits part, and use a map or a switch instead, etc).
const char* hex_char_to_bin(char c)
{
// TODO handle default / error
switch(toupper(c))
{
case '0': return "0000";
case '1': return "0001";
case '2': return "0010";
case '3': return "0011";
case '4': return "0100";
case '5': return "0101";
case '6': return "0110";
case '7': return "0111";
case '8': return "1000";
case '9': return "1001";
case 'A': return "1010";
case 'B': return "1011";
case 'C': return "1100";
case 'D': return "1101";
case 'E': return "1110";
case 'F': return "1111";
}
}
std::string hex_str_to_bin_str(const std::string& hex)
{
// TODO use a loop from <algorithm> or smth
std::string bin;
for(unsigned i = 0; i != hex.length(); ++i)
bin += hex_char_to_bin(hex[i]);
return bin;
}
The simplest solution without using bitset or any library, only using shift operators and std::hex to convert the whole hex-string.
sample code to convert hex-string to binary-digits :
string s = "FF 0F F0 C3 10";
stringstream ss;
ss << hex << s;
unsigned int n;
while(ss >> n){
for (int i = 8 -1; i >= 0; i--)
cout << ((n >> i) & 1) ? "1" : "0";
cout << std::endl;
}
sample output :
11111111
00001111
11110000
11000011
00001010
full code snipet
The following code includes two functions that will do exactly as you desire. This is based on the answer by Silex but with a few extra string operations to match the example output you gave in your question.
#include <iostream>
#include <sstream>
#include <bitset>
#include <string>
#include <boost/algorithm/string.hpp>
using namespace std;
const unsigned g_unMaxBits = 32;
string Hex2Bin(const string& s)
{
stringstream ss;
ss << hex << s;
unsigned n;
ss >> n;
bitset<g_unMaxBits> b(n);
unsigned x = 0;
if (boost::starts_with(s, "0x") || boost::starts_with(s, "0X")) x = 2;
return b.to_string().substr(32 - 4*(s.length()-x));
}
string Bin2Hex(const string& s)
{
bitset<g_unMaxBits> bs(s);
unsigned n = bs.to_ulong();
stringstream ss;
ss << hex << n;
return "0x" + boost::to_upper_copy(ss.str());
}
int main()
{
cout << "0xA1 => " << Hex2Bin("0xA1") << endl;
cout << "B3 => " << Hex2Bin("B3") << endl;
cout << "11110001 => " << Bin2Hex("11110001") << endl;
return 0;
}