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 
11 #include <tlx/string/hexdump.hpp>
12 
13 #include <sstream>
14 #include <stdexcept>
15 
16 namespace tlx {
17 
18 /******************************************************************************/
19 // Uppercase Hexdump Methods
20 
21 std::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 
42 std::string hexdump(const std::string& str) {
43  return hexdump(str.data(), str.size());
44 }
45 
46 std::string hexdump(const std::vector<char>& data) {
47  return hexdump(data.data(), data.size());
48 }
49 
50 std::string hexdump(const std::vector<uint8_t>& data) {
51  return hexdump(data.data(), data.size());
52 }
53 
54 std::string hexdump_sourcecode(
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 
95 std::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 
116 std::string hexdump_lc(const std::string& str) {
117  return hexdump_lc(str.data(), str.size());
118 }
119 
120 std::string hexdump_lc(const std::vector<char>& data) {
121  return hexdump_lc(data.data(), data.size());
122 }
123 
124 std::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 
131 std::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