9 #include <botan/mem_ops.h>
19 static const byte BIN_TO_HEX_UPPER[16] = {
20 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
21 'A',
'B',
'C',
'D',
'E',
'F' };
23 static const byte BIN_TO_HEX_LOWER[16] = {
24 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
25 'a',
'b',
'c',
'd',
'e',
'f' };
27 const byte* tbl = uppercase ? BIN_TO_HEX_UPPER : BIN_TO_HEX_LOWER;
29 for(
size_t i = 0; i != input_length; ++i)
32 output[2*i ] = tbl[(x >> 4) & 0x0F];
33 output[2*i+1] = tbl[(x ) & 0x0F];
47 std::string output(2 * input_length, 0);
50 hex_encode(&output[0], input, input_length, uppercase);
58 size_t& input_consumed,
70 static const byte HEX_TO_BIN[256] = {
71 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
72 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
73 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
74 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
75 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
76 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,
77 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
78 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
79 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
80 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C,
81 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
82 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
83 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
84 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
85 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
86 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
87 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
88 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
89 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
90 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
91 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
92 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
93 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
94 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
95 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
96 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
98 byte* out_ptr = output;
99 bool top_nibble =
true;
103 for(
size_t i = 0; i != input_length; ++i)
105 const byte bin = HEX_TO_BIN[
static_cast<byte>(input[i])];
109 if(bin == 0x80 && ignore_ws)
112 std::string bad_char(1, input[i]);
115 else if(bad_char ==
"\n")
118 throw std::invalid_argument(
119 std::string(
"hex_decode: invalid hex character '") +
123 *out_ptr |= bin << (top_nibble*4);
125 top_nibble = !top_nibble;
130 input_consumed = input_length;
131 size_t written = (out_ptr - output);
152 size_t written =
hex_decode(output, input, input_length,
153 consumed, ignore_ws);
155 if(consumed != input_length)
156 throw std::invalid_argument(
"hex_decode: input did not have full bytes");
162 const std::string& input,
165 return hex_decode(output, &input[0], input.length(), ignore_ws);
186 return hex_decode(&input[0], input.size(), ignore_ws);
size_t hex_decode(byte output[], const char input[], size_t input_length, size_t &input_consumed, bool ignore_ws)
void clear_mem(T *ptr, size_t n)
void hex_encode(char output[], const byte input[], size_t input_length, bool uppercase)