-
Notifications
You must be signed in to change notification settings - Fork 1
/
hexstring.h
198 lines (155 loc) · 3.74 KB
/
hexstring.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#ifndef HEXSTRING_H_
#define HEXSTRING_H_
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
/**
* Byte multiplier: a printed byte uses 3 characters
*/
#define BYTE_MULT 3
/**
* Convert a 2-bytes string to an uint8_t integer (e.g. "1A\0" -> 0x1A)
*
* @param str hexstring to convert, of expected size BYTE_MULT
* @return converted uint8_t integer
*/
uint8_t str_to_hex(char *str) {
assert(str != NULL);
uint8_t hex = 0;
if(isdigit(str[0])) {
hex |= (str[0] & 0x0F) << 4;
} else {
hex |= ((str[0]+0x09) & 0x0F) << 4;
}
if(isdigit(str[1])) {
hex |= (str[1] & 0x0F);
} else {
hex |= ((str[1]+0x09) & 0x0F);
}
return hex;
}
/**
* Convert an uint8_t integer to a 2-bytes hexstring (e.g. 0x1A -> "1A\0")
*
* @param hex uint8_t integer to convert
* @param str destination hexstring, of expected size BYTE_MULT
*/
void hex_to_str(uint8_t hex, char *str) {
assert(str != NULL);
str[0] = (hex & 0xF0) >> 4;
str[1] = (hex & 0x0F);
str[2] = '\0';
if(str[0]<0x0A) {
str[0] |= 0x30;
} else {
str[0] |= 0x40;
str[0] -= 0x09;
}
if(str[1]<0x0A) {
str[1] |= 0x30;
} else {
str[1] |= 0x40;
str[1] -= 0x09;
}
}
/**
* Check if the character is hexadecimal.
*
* @param c character to check
* @return
* - 1 if hexadecimal
* - 0 if not hexadecimal
*/
int is_hex(char c) {
if ((c >= 'A' && c <= 'F') || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'))
return 1;
return 0;
}
/**
* Return the length of the hexstring.
*
* @param hexstr input string
* @return hexstr length
*/
int hexstr_size(const char *hexstr) {
assert(hexstr != NULL);
int size = 0;
const char *p = hexstr;
/*
* Parse an hexstring and calculate it's size.
* Analyze three bytes at a time, in this format: HEX HEX (SPACE|NULL)
* (Ex. "FF ", "2A ", "EE")
*/
while ( is_hex(p[0]) && is_hex(p[1]) && (p[2] == ' ' || p[2] == '\n' || p[2] == '\0') ) {
//printf("p[0] = %c, p[1] = %c, p[2] = %c\n", p[0], p[1], p[2] == '\0' ? 'N' : p[2]);
size++;
p += BYTE_MULT;
}
return size;
}
/**
* Create a raw buffer from an hexstring. The buffer must be manually free()d.
*
* @param hexstr hexstring to convert
* @param size hexstring size
* @return pointer to the converted raw buffer
*/
uint8_t *hexstr_to_raw(const char *hexstr, int *size) {
assert(hexstr != NULL);
assert(size != NULL);
char *raw = NULL;
const char *p = hexstr;
*size = hexstr_size(hexstr);
raw = (char *) malloc(*size); // malloc the raw buffer
char hex[BYTE_MULT];
int i = 0;
/*
* Parse an hexstring.
* Analyze three bytes at a time, in this format: HEX HEX (SPACE|NULL)
* (Ex. "FF ", "2A ", "EE")
*/
while ( is_hex(p[0]) && is_hex(p[1]) && (p[2] == ' ' || p[2] == '\n' || p[2] == '\0') ) {
//printf("p[0] = %c, p[1] = %c, p[2] = %c\n", p[0], p[1], p[2] == '\0' ? 'N' : p[2]);
// extract a single byte
hex[0] = p[0];
hex[1] = p[1];
hex[2] = '\0';
raw[i] = str_to_hex(hex);
i++;
p += BYTE_MULT;
}
//hex_dump(raw, size);
return raw;
}
/**
* Create an hexstring from a raw buffer. The buffer must be manually free()d.
*
* @param raw raw buffer to convert
* @param size raw buffer size
* @return converted hexstring
*/
char *raw_to_hexstr(const uint8_t *raw, int size) {
assert(raw != NULL);
if(size == 0) return NULL;
char *hexstr = NULL;
hexstr = (char *) malloc(size*BYTE_MULT); // malloc the hexstring
char hex[BYTE_MULT];
int i = 0;
char *p = hexstr;
/*
* Parse an hexstring.
* Analyze three bytes at a time, in this format: HEX HEX (SPACE|NULL)
* (Ex. "FF ", "2A ", "EE")
*/
for (i=0; i<size; i++, p+=BYTE_MULT) {
// extract a single byte
hex_to_str(raw[i], hex);
p[0] = hex[0];
p[1] = hex[1];
p[2] = ' ';
}
hexstr[(size*BYTE_MULT)-1] = '\0';
return hexstr;
}
#endif /* HEXSTRING_H_ */