Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link
URL Rewriter Bot
URL Rewriter Bot

I found this question, but the accepted answer didn't look like a C++ way of solving the task to me (this doesn't mean it's a bad answer or anything, just explaining motivation behind adding this one). I recollected this nice answerthis nice answer and decided to implement something similar. Here is complete code of what I ended up with (it also works for std::wstring):

I found this question, but the accepted answer didn't look like a C++ way of solving the task to me (this doesn't mean it's a bad answer or anything, just explaining motivation behind adding this one). I recollected this nice answer and decided to implement something similar. Here is complete code of what I ended up with (it also works for std::wstring):

I found this question, but the accepted answer didn't look like a C++ way of solving the task to me (this doesn't mean it's a bad answer or anything, just explaining motivation behind adding this one). I recollected this nice answer and decided to implement something similar. Here is complete code of what I ended up with (it also works for std::wstring):

Clarify meaning of the first sentence.
Source Link
xaizek
  • 5.3k
  • 1
  • 40
  • 68

I found this question, but the accepted answer didn't look like a C++ way of solving the task to me (this doesn't mean it's a bad answer or anything, just explaining motivation behind adding this one). I recollected this nice answer and decided to implement something similar. Here is complete code of what I ended up with (it also works for std::wstring):

I found this question, but the accepted answer didn't look like a C++ way of solving the task to me. I recollected this nice answer and decided to implement something similar. Here is complete code of what I ended up with (it also works for std::wstring):

I found this question, but the accepted answer didn't look like a C++ way of solving the task to me (this doesn't mean it's a bad answer or anything, just explaining motivation behind adding this one). I recollected this nice answer and decided to implement something similar. Here is complete code of what I ended up with (it also works for std::wstring):

Update code to handle odd number of hex characters correctly
Source Link
xaizek
  • 5.3k
  • 1
  • 40
  • 68
#include <cctype> #include <cstdlib>  #include <algorithm> #include <iostream> #include <iterator> #include <ostream> #include <stdexcept> #include <string> #include <vector> template <typename OutputIt> class hex_ostream_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void> { OutputIt out; int digitCount; int number; public: hex_ostream_iterator(OutputIt out) : out(out), digitCount(0), number(0) { } hex_ostream_iterator<OutputIt> & operator=(char c) { number = (number << 4) | char2int(c); digitCount++; if (digitCount == 2) { digitCount = 0; *out++ = number; number = 0; } return *this; } hex_ostream_iterator<OutputIt> & operator*() { return *this; } hex_ostream_iterator<OutputIt> & operator++() { return *this; } hex_ostream_iterator<OutputIt> & operator++(int) { return *this; } private: int char2int(char c) { static const std::string HEX_CHARS = "0123456789abcdef"; const char lowerC = std::tolower(c); const std::string::size_type pos = HEX_CHARS.find_first_of(lowerC); if (pos == std::string::npos) { throw std::runtime_error(std::string("Not a hex digit: ") + c); } return pos; } }; template <typename OutputIt> hex_ostream_iterator<OutputIt> hex_iterator(OutputIt out) { return hex_ostream_iterator<OutputIt>(out); } inttemplate <typename InputIt, typename OutputIt> mainhex_ostream_iterator<OutputIt> from_hex_string(InputIt first, InputIt last, OutputIt out) { if (std::stringdistance(first, inputlast) % 2 == 1) {  *out = "61A062a063";'0';  // "a b c" ++out;  } return std::copy(therefirst, arelast, non-breakableout); } int main(int spacesargc, char *argv[]) {  if (argc != 2) {  std::vector<unsignedcout char><< bytes;"Usage: " << argv[0] << " hexstring" << std::endl; return EXIT_FAILURE; } const std::copystring input = argv[1]; std::vector<unsigned char> bytes; from_hex_string(input.begin(), input.end(),  hex_iterator(std::back_inserter(bytes))); typedef std::ostream_iterator<unsigned char> osit; std::copy(bytes.begin(), bytes.end(), std::ostream_iterator<unsigned char>osit(std::cout)); return 0;EXIT_SUCCESS; } 

And the output of g++ hex2bytes.cpp/hex2bytes &&61a062a063 | hexdump -C:

00000000 61 a0 62 a0 63 |a.b.c| 00000005 

And of ./a.outhex2bytes 6a062a063 | hexdump -C (note odd number of characters):

00000000 6106 a0 62 a0 63 |a|..b.c| 00000005 
#include <cctype> #include <algorithm> #include <iostream> #include <iterator> #include <ostream> #include <stdexcept> #include <string> #include <vector> template <typename OutputIt> class hex_ostream_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void> { OutputIt out; int digitCount; int number; public: hex_ostream_iterator(OutputIt out) : out(out), digitCount(0), number(0) { } hex_ostream_iterator<OutputIt> & operator=(char c) { number = (number << 4) | char2int(c); digitCount++; if (digitCount == 2) { digitCount = 0; *out++ = number; number = 0; } return *this; } hex_ostream_iterator<OutputIt> & operator*() { return *this; } hex_ostream_iterator<OutputIt> & operator++() { return *this; } hex_ostream_iterator<OutputIt> & operator++(int) { return *this; } private: int char2int(char c) { static const std::string HEX_CHARS = "0123456789abcdef"; const char lowerC = std::tolower(c); const std::string::size_type pos = HEX_CHARS.find_first_of(lowerC); if (pos == std::string::npos) { throw std::runtime_error(std::string("Not a hex digit: ") + c); } return pos; } }; template <typename OutputIt> hex_ostream_iterator<OutputIt> hex_iterator(OutputIt out) { return hex_ostream_iterator<OutputIt>(out); } int main() { std::string input = "61A062a063"; // "a b c" (there are non-breakable spaces) std::vector<unsigned char> bytes; std::copy(input.begin(), input.end(), hex_iterator(std::back_inserter(bytes))); std::copy(bytes.begin(), bytes.end(), std::ostream_iterator<unsigned char>(std::cout)); return 0; } 

And the output of g++ hex2bytes.cpp && ./a.out | hexdump -C:

00000000 61 a0 62 a0 63 |a.b.c| 00000005 
#include <cctype> #include <cstdlib>  #include <algorithm> #include <iostream> #include <iterator> #include <ostream> #include <stdexcept> #include <string> #include <vector> template <typename OutputIt> class hex_ostream_iterator : public std::iterator<std::output_iterator_tag, void, void, void, void> { OutputIt out; int digitCount; int number; public: hex_ostream_iterator(OutputIt out) : out(out), digitCount(0), number(0) { } hex_ostream_iterator<OutputIt> & operator=(char c) { number = (number << 4) | char2int(c); digitCount++; if (digitCount == 2) { digitCount = 0; *out++ = number; number = 0; } return *this; } hex_ostream_iterator<OutputIt> & operator*() { return *this; } hex_ostream_iterator<OutputIt> & operator++() { return *this; } hex_ostream_iterator<OutputIt> & operator++(int) { return *this; } private: int char2int(char c) { static const std::string HEX_CHARS = "0123456789abcdef"; const char lowerC = std::tolower(c); const std::string::size_type pos = HEX_CHARS.find_first_of(lowerC); if (pos == std::string::npos) { throw std::runtime_error(std::string("Not a hex digit: ") + c); } return pos; } }; template <typename OutputIt> hex_ostream_iterator<OutputIt> hex_iterator(OutputIt out) { return hex_ostream_iterator<OutputIt>(out); } template <typename InputIt, typename OutputIt> hex_ostream_iterator<OutputIt> from_hex_string(InputIt first, InputIt last, OutputIt out) { if (std::distance(first, last) % 2 == 1) {  *out = '0';   ++out;  } return std::copy(first, last, out); } int main(int argc, char *argv[]) {  if (argc != 2) {  std::cout << "Usage: " << argv[0] << " hexstring" << std::endl; return EXIT_FAILURE; } const std::string input = argv[1]; std::vector<unsigned char> bytes; from_hex_string(input.begin(), input.end(),  hex_iterator(std::back_inserter(bytes))); typedef std::ostream_iterator<unsigned char> osit; std::copy(bytes.begin(), bytes.end(), osit(std::cout)); return EXIT_SUCCESS; } 

And the output of ./hex2bytes 61a062a063 | hexdump -C:

00000000 61 a0 62 a0 63 |a.b.c| 00000005 

And of ./hex2bytes 6a062a063 | hexdump -C (note odd number of characters):

00000000 06 a0 62 a0 63 |..b.c| 00000005 
Source Link
xaizek
  • 5.3k
  • 1
  • 40
  • 68
Loading