tlx
hexdump.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 * tlx/string/hexdump.cpp
3 *
4 * Part of tlx - http://panthema.net/tlx
5 *
6 * Copyright (C) 2007-2017 Timo Bingmann <tb@panthema.net>
7 *
8 * All rights reserved. Published under the Boost Software License, Version 1.0
9 ******************************************************************************/
10
12
13#include <sstream>
14#include <stdexcept>
15
16namespace tlx {
17
18/******************************************************************************/
19// Uppercase Hexdump Methods
20
21std::string hexdump(const void* const data, size_t size) {
22 const unsigned char* const cdata =
23 static_cast<const unsigned char*>(data);
24
25 std::string out;
26 out.resize(size * 2);
27
28 static const char xdigits[16] = {
29 '0', '1', '2', '3', '4', '5', '6', '7',
30 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
31 };
32
33 std::string::iterator oi = out.begin();
34 for (const unsigned char* si = cdata; si != cdata + size; ++si) {
35 *oi++ = xdigits[(*si & 0xF0) >> 4];
36 *oi++ = xdigits[(*si & 0x0F)];
37 }
38
39 return out;
40}
41
42std::string hexdump(const std::string& str) {
43 return hexdump(str.data(), str.size());
44}
45
46std::string hexdump(const std::vector<char>& data) {
47 return hexdump(data.data(), data.size());
48}
49
50std::string hexdump(const std::vector<uint8_t>& data) {
51 return hexdump(data.data(), data.size());
52}
53
55 const std::string& str, const std::string& var_name) {
56
57 std::ostringstream header;
58 header << "const uint8_t " << var_name << "[" << str.size() << "] = {\n";
59
60 static const int perline = 16;
61
62 std::string out = header.str();
63 out.reserve(out.size() + (str.size() * 5) - 1 + (str.size() / 16) + 4);
64
65 static const char xdigits[16] = {
66 '0', '1', '2', '3', '4', '5', '6', '7',
67 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
68 };
69
70 std::string::size_type ci = 0;
71
72 for (std::string::const_iterator si = str.begin(); si != str.end();
73 ++si, ++ci) {
74
75 out += "0x";
76 out += xdigits[(*si & 0xF0) >> 4];
77 out += xdigits[(*si & 0x0F)];
78
79 if (ci + 1 < str.size()) {
80 out += ',';
81
82 if (ci % perline == perline - 1)
83 out += '\n';
84 }
85 }
86
87 out += "\n};\n";
88
89 return out;
90}
91
92/******************************************************************************/
93// Lowercase Hexdump Methods
94
95std::string hexdump_lc(const void* const data, size_t size) {
96 const unsigned char* const cdata =
97 static_cast<const unsigned char*>(data);
98
99 std::string out;
100 out.resize(size * 2);
101
102 static const char xdigits[16] = {
103 '0', '1', '2', '3', '4', '5', '6', '7',
104 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
105 };
106
107 std::string::iterator oi = out.begin();
108 for (const unsigned char* si = cdata; si != cdata + size; ++si) {
109 *oi++ = xdigits[(*si & 0xF0) >> 4];
110 *oi++ = xdigits[(*si & 0x0F)];
111 }
112
113 return out;
114}
115
116std::string hexdump_lc(const std::string& str) {
117 return hexdump_lc(str.data(), str.size());
118}
119
120std::string hexdump_lc(const std::vector<char>& data) {
121 return hexdump_lc(data.data(), data.size());
122}
123
124std::string hexdump_lc(const std::vector<uint8_t>& data) {
125 return hexdump_lc(data.data(), data.size());
126}
127
128/******************************************************************************/
129// Parser for Hex Digit Sequence
130
131std::string parse_hexdump(const std::string& str) {
132 std::string out;
133
134 for (std::string::const_iterator si = str.begin(); si != str.end(); ++si) {
135
136 unsigned char c = 0;
137
138 // read first character of pair
139 switch (*si) {
140 case '0': c |= 0x00;
141 break;
142 case '1': c |= 0x10;
143 break;
144 case '2': c |= 0x20;
145 break;
146 case '3': c |= 0x30;
147 break;
148 case '4': c |= 0x40;
149 break;
150 case '5': c |= 0x50;
151 break;
152 case '6': c |= 0x60;
153 break;
154 case '7': c |= 0x70;
155 break;
156 case '8': c |= 0x80;
157 break;
158 case '9': c |= 0x90;
159 break;
160 case 'A':
161 case 'a': c |= 0xA0;
162 break;
163 case 'B':
164 case 'b': c |= 0xB0;
165 break;
166 case 'C':
167 case 'c': c |= 0xC0;
168 break;
169 case 'D':
170 case 'd': c |= 0xD0;
171 break;
172 case 'E':
173 case 'e': c |= 0xE0;
174 break;
175 case 'F':
176 case 'f': c |= 0xF0;
177 break;
178 default: throw std::runtime_error("Invalid string for hex conversion");
179 }
180
181 ++si;
182 if (si == str.end())
183 throw std::runtime_error("Invalid string for hex conversion");
184
185 // read second character of pair
186 switch (*si) {
187 case '0': c |= 0x00;
188 break;
189 case '1': c |= 0x01;
190 break;
191 case '2': c |= 0x02;
192 break;
193 case '3': c |= 0x03;
194 break;
195 case '4': c |= 0x04;
196 break;
197 case '5': c |= 0x05;
198 break;
199 case '6': c |= 0x06;
200 break;
201 case '7': c |= 0x07;
202 break;
203 case '8': c |= 0x08;
204 break;
205 case '9': c |= 0x09;
206 break;
207 case 'A':
208 case 'a': c |= 0x0A;
209 break;
210 case 'B':
211 case 'b': c |= 0x0B;
212 break;
213 case 'C':
214 case 'c': c |= 0x0C;
215 break;
216 case 'D':
217 case 'd': c |= 0x0D;
218 break;
219 case 'E':
220 case 'e': c |= 0x0E;
221 break;
222 case 'F':
223 case 'f': c |= 0x0F;
224 break;
225 default: throw std::runtime_error("Invalid string for hex conversion");
226 }
227
228 out += static_cast<char>(c);
229 }
230
231 return out;
232}
233
234} // namespace tlx
235
236/******************************************************************************/
std::string hexdump_lc(const void *const data, size_t size)
Dump a (binary) string as a sequence of lowercase hexadecimal pairs.
Definition: hexdump.cpp:95
std::string parse_hexdump(const std::string &str)
Read a string as a sequence of hexadecimal pairs.
Definition: hexdump.cpp:131
std::string hexdump_sourcecode(const std::string &str, const std::string &var_name)
Dump a (binary) string into a C source code snippet.
Definition: hexdump.cpp:54
std::string hexdump(const void *const data, size_t size)
Dump a (binary) string as a sequence of uppercase hexadecimal pairs.
Definition: hexdump.cpp:21