Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

hex.cpp
Go to the documentation of this file.
1 /*
2 * Hex Encoding and Decoding
3 * (C) 2010 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/hex.h>
9 #include <botan/mem_ops.h>
10 #include <botan/exceptn.h>
11
12 namespace Botan {
13
14 void hex_encode(char output[],
15 const uint8_t input[],
16 size_t input_length,
17 bool uppercase)
18 {
19 static const uint8_t BIN_TO_HEX_UPPER[16] = {
20 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
21 'A', 'B', 'C', 'D', 'E', 'F' };
22
23 static const uint8_t BIN_TO_HEX_LOWER[16] = {
24 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
25 'a', 'b', 'c', 'd', 'e', 'f' };
26
27 const uint8_t* tbl = uppercase ? BIN_TO_HEX_UPPER : BIN_TO_HEX_LOWER;
28
29 for(size_t i = 0; i != input_length; ++i)
30 {
31 uint8_t x = input[i];
32 output[2*i ] = tbl[(x >> 4) & 0x0F];
33 output[2*i+1] = tbl[(x ) & 0x0F];
34 }
35 }
36
37 std::string hex_encode(const uint8_t input[],
38 size_t input_length,
39 bool uppercase)
40 {
41 std::string output(2 * input_length, 0);
42
43 if(input_length)
44 hex_encode(&output.front(), input, input_length, uppercase);
45
46 return output;
47 }
48
49 size_t hex_decode(uint8_t output[],
50 const char input[],
51 size_t input_length,
52 size_t& input_consumed,
53 bool ignore_ws)
54 {
55 /*
56 * Mapping of hex characters to either their binary equivalent
57 * or to an error code.
58 * If valid hex (0-9 A-F a-f), the value.
59 * If whitespace, then 0x80
60 * Otherwise 0xFF
61 * Warning: this table assumes ASCII character encodings
62 */
63
64 static const uint8_t HEX_TO_BIN[256] = {
65 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
66 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
67 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
68 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
69 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
70 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,
71 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
72 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
73 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
74 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C,
75 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
76 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
77 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
78 0xFF, 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, 0xFF, 0xFF, 0xFF,
81 0xFF, 0xFF, 0xFF, 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 };
91
92 uint8_t* out_ptr = output;
93 bool top_nibble = true;
94
95 clear_mem(output, input_length / 2);
96
97 for(size_t i = 0; i != input_length; ++i)
98 {
99 const uint8_t bin = HEX_TO_BIN[static_cast<uint8_t>(input[i])];
100
101 if(bin >= 0x10)
102 {
103 if(bin == 0x80 && ignore_ws)
104 continue;
105
106 std::string bad_char(1, input[i]);
107 if(bad_char == "\t")
108 bad_char = "\\t";
109 else if(bad_char == "\n")
110 bad_char = "\\n";
111
112 throw Invalid_Argument(
113 std::string("hex_decode: invalid hex character '") +
114 bad_char + "'");
115 }
116
117 if(top_nibble)
118 *out_ptr |= bin << 4;
119 else
120 *out_ptr |= bin;
121
122 top_nibble = !top_nibble;
123 if(top_nibble)
124 ++out_ptr;
125 }
126
127 input_consumed = input_length;
128 size_t written = (out_ptr - output);
129
130 /*
131 * We only got half of a uint8_t at the end; zap the half-written
132 * output and mark it as unread
133 */
134 if(!top_nibble)
135 {
136 *out_ptr = 0;
137 input_consumed -= 1;
138 }
139
140 return written;
141 }
142
143 size_t hex_decode(uint8_t output[],
144 const char input[],
145 size_t input_length,
146 bool ignore_ws)
147 {
148 size_t consumed = 0;
149 size_t written = hex_decode(output, input, input_length,
150 consumed, ignore_ws);
151
152 if(consumed != input_length)
153 throw Invalid_Argument("hex_decode: input did not have full bytes");
154
155 return written;
156 }
157
158 size_t hex_decode(uint8_t output[],
159 const std::string& input,
160 bool ignore_ws)
161 {
162 return hex_decode(output, input.data(), input.length(), ignore_ws);
163 }
164
165 secure_vector<uint8_t> hex_decode_locked(const char input[],
166 size_t input_length,
167 bool ignore_ws)
168 {
169 secure_vector<uint8_t> bin(1 + input_length / 2);
170
171 size_t written = hex_decode(bin.data(),
172 input,
173 input_length,
174 ignore_ws);
175
176 bin.resize(written);
177 return bin;
178 }
179
180 secure_vector<uint8_t> hex_decode_locked(const std::string& input,
181 bool ignore_ws)
182 {
183 return hex_decode_locked(input.data(), input.size(), ignore_ws);
184 }
185
186 std::vector<uint8_t> hex_decode(const char input[],
187 size_t input_length,
188 bool ignore_ws)
189 {
190 std::vector<uint8_t> bin(1 + input_length / 2);
191
192 size_t written = hex_decode(bin.data(),
193 input,
194 input_length,
195 ignore_ws);
196
197 bin.resize(written);
198 return bin;
199 }
200
201 std::vector<uint8_t> hex_decode(const std::string& input,
202 bool ignore_ws)
203 {
204 return hex_decode(input.data(), input.size(), ignore_ws);
205 }
206
207 }
Botan::hex_encode
void hex_encode(char output[], const uint8_t input[], size_t input_length, bool uppercase)
Definition: hex.cpp:14
Botan::Invalid_Argument
Definition: exceptn.h:136
Botan::hex_decode_locked
secure_vector< uint8_t > hex_decode_locked(const char input[], size_t input_length, bool ignore_ws)
Definition: hex.cpp:165
Botan::clear_mem
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:112
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:65
Botan
Definition: alg_id.cpp:13
Botan::hex_decode
size_t hex_decode(uint8_t output[], const char input[], size_t input_length, size_t &input_consumed, bool ignore_ws)
Definition: hex.cpp:49