Converting a hex string to a byte array

后端 未结 19 2139
时光取名叫无心
时光取名叫无心 2020-11-22 12:10

What is the best way to convert a variable length hex string e.g. \"01A1\" to a byte array containing that data.

i.e converting this:

st         


        
19条回答
  •  迷失自我
    2020-11-22 13:07

    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):

    #include 
    #include 
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    template 
    class hex_ostream_iterator :
        public std::iterator
    {
        OutputIt out;
        int digitCount;
        int number;
    
    public:
        hex_ostream_iterator(OutputIt out) : out(out), digitCount(0), number(0)
        {
        }
    
        hex_ostream_iterator &
        operator=(char c)
        {
            number = (number << 4) | char2int(c);
            digitCount++;
    
            if (digitCount == 2) {
                digitCount = 0;
                *out++ = number;
                number = 0;
            }
            return *this;
        }
    
        hex_ostream_iterator &
        operator*()
        {
            return *this;
        }
    
        hex_ostream_iterator &
        operator++()
        {
            return *this;
        }
    
        hex_ostream_iterator &
        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 
    hex_ostream_iterator
    hex_iterator(OutputIt out)
    {
        return hex_ostream_iterator(out);
    }
    
    template 
    hex_ostream_iterator
    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 bytes;
        from_hex_string(input.begin(), input.end(),
                        hex_iterator(std::back_inserter(bytes)));
    
        typedef std::ostream_iterator 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
    

提交回复
热议问题