1
/*
2
*******************************************************************************
3
\file hex.c
4
\brief Hexadecimal strings
5
\project bee2 [cryptographic library]
6
\author (C) Sergey Agievich [agievich@{bsu.by|gmail.com}]
7
\created 2015.10.29
8
\version 2016.06.19
9
\license This program is released under the GNU General Public License
10
version 3. See Copyright Notices in bee2/info.h.
11
*******************************************************************************
12
*/
13

14
#include "bee2/core/hex.h"
15
#include "bee2/core/mem.h"
16
#include "bee2/core/str.h"
17
#include "bee2/core/util.h"
18
#include "bee2/core/word.h"
19

20
/*
21
*******************************************************************************
22
Таблицы
23
*******************************************************************************
24
*/
25

26
static const char hex_upper[] = "0123456789ABCDEF";
27
static const char hex_lower[] = "0123456789abcdef";
28

29
static const octet hex_dec_table[256] = {
30
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
31
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
32
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
33
	0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
34
	0xFF,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
35
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
36
	0xFF,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
37
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
38
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
39
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
40
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
41
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
42
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
43
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
44
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
45
	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
46
};
47

48
/*
49
*******************************************************************************
50
Октеты
51
*******************************************************************************
52
*/
53

54 1
static octet hexToO(const char* hex)
55
{
56
	register octet hi;
57
	register octet lo;
58 1
	ASSERT(memIsValid(hex, 2));
59 1
	hi = hex_dec_table[(octet)hex[0]];
60 1
	lo = hex_dec_table[(octet)hex[1]];
61 1
	ASSERT(hi != 0xFF && lo != 0xFF);
62 1
	return hi << 4 | lo;
63
}
64

65 1
static void hexFromOUpper(char* hex, register octet o)
66
{
67 1
	ASSERT(memIsValid(hex, 2));
68 1
	hex[0] = hex_upper[o >> 4];
69 1
	hex[1] = hex_upper[o & 15];
70 1
	o = 0;
71
}
72

73 1
static void hexFromOLower(char* hex, register octet o)
74
{
75 1
	ASSERT(memIsValid(hex, 2));
76 1
	hex[0] = hex_lower[o >> 4];
77 1
	hex[1] = hex_lower[o & 15];
78 1
	o = 0;
79
}
80

81
/*
82
*******************************************************************************
83
Проверка
84
*******************************************************************************
85
*/
86

87 1
bool_t hexIsValid(const char* hex)
88
{
89 1
	if (!strIsValid(hex) || strLen(hex) % 2)
90 1
		return FALSE;
91 1
	for (; *hex; ++hex)
92 1
		if (hex_dec_table[(octet)*hex] == 0xFF)
93 1
			return FALSE;
94 1
	return TRUE;
95
}
96

97
/*
98
*******************************************************************************
99
Регистр
100
*******************************************************************************
101
*/
102

103 1
void hexUpper(char* hex)
104
{
105 1
	ASSERT(hexIsValid(hex));
106 1
	for (; *hex; hex += 2)
107 1
		hexFromOUpper(hex, hexToO(hex));
108
}
109

110 1
void hexLower(char* hex)
111
{
112 1
	ASSERT(hexIsValid(hex));
113 1
	for (; *hex; hex += 2)
114 1
		hexFromOLower(hex, hexToO(hex));
115
}
116

117
/*
118
*******************************************************************************
119
Сравнения
120
*******************************************************************************
121
*/
122

123 1
bool_t SAFE(hexEq)(const void* buf, const char* hex)
124
{
125 1
	register word diff = 0;
126
	size_t count;
127 1
	ASSERT(hexIsValid(hex));
128 1
	ASSERT(memIsValid(buf, strLen(hex) / 2));
129 1
	count = strLen(hex);
130 1
	for (; count; count -= 2, hex += 2, buf = (const octet*)buf + 1)
131 1
		diff |= *(const octet*)buf ^ hexToO(hex);
132 1
	return wordEq(diff, 0);
133
}
134

135 0
bool_t FAST(hexEq)(const void* buf, const char* hex)
136
{
137
	size_t count;
138 0
	ASSERT(hexIsValid(hex));
139 0
	ASSERT(memIsValid(buf, strLen(hex) / 2));
140 0
	count = strLen(hex);
141 0
	for (; count; count -= 2, hex += 2, buf = (const octet*)buf + 1)
142 0
		if (*(const octet*)buf != hexToO(hex))
143 0
			return FALSE;
144 0
	return TRUE;
145
}
146

147 1
bool_t SAFE(hexEqRev)(const void* buf, const char* hex)
148
{
149 1
	register word diff = 0;
150
	size_t count;
151 1
	ASSERT(hexIsValid(hex));
152 1
	ASSERT(memIsValid(buf, strLen(hex) / 2));
153 1
	count = strLen(hex);
154 1
	hex = hex + count;
155 1
	for (; count; count -= 2, buf = (const octet*)buf + 1)
156 1
		diff |= *(const octet*)buf ^ hexToO(hex -= 2);
157 1
	return wordEq(diff, 0);
158
}
159

160 0
bool_t FAST(hexEqRev)(const void* buf, const char* hex)
161
{
162
	size_t count;
163 0
	ASSERT(hexIsValid(hex));
164 0
	ASSERT(memIsValid(buf, strLen(hex) / 2));
165 0
	count = strLen(hex);
166 0
	hex = hex + count;
167 0
	for (; count; count -= 2, buf = (const octet*)buf + 1)
168 0
		if (*(const octet*)buf != hexToO(hex -= 2))
169 0
			return FALSE;
170 0
	return TRUE;
171
}
172

173
/*
174
*******************************************************************************
175
Кодирование
176
*******************************************************************************
177
*/
178

179 1
void hexFrom(char* dest, const void* src, size_t count)
180
{
181 1
	ASSERT(memIsDisjoint2(src, count, dest, 2 * count + 1));
182 1
	for (; count--; dest += 2, src = (const octet*)src + 1)
183 1
		hexFromOUpper(dest, *(const octet*)src);
184 1
	*dest = '\0';
185
}
186

187 1
void hexFromRev(char* dest, const void* src, size_t count)
188
{
189 1
	ASSERT(memIsDisjoint2(src, count, dest, 2 * count + 1));
190 1
	dest = dest + 2 * count;
191 1
	*dest = '\0';
192 1
	for (; count--; src = (const octet*)src + 1)
193 1
		hexFromOUpper(dest -= 2, *(const octet*)src);
194
}
195

196 1
void hexTo(void* dest, const char* src)
197
{
198
	size_t count;
199 1
	ASSERT(hexIsValid(src));
200 1
	ASSERT(memIsDisjoint2(src, strLen(src) + 1, dest, strLen(src) / 2));
201 1
	count = strLen(src);
202 1
	for (; count; count -= 2, src += 2, dest = (octet*)dest + 1)
203 1
		*(octet*)dest = hexToO(src);
204
}
205

206 1
void hexToRev(void* dest, const char* src)
207
{
208
	size_t count;
209 1
	ASSERT(hexIsValid(src));
210 1
	ASSERT(memIsDisjoint2(src, strLen(src) + 1, dest, strLen(src) / 2));
211 1
	count = strLen(src);
212 1
	src = src + count;
213 1
	for (; count; count -= 2, dest = (octet*)dest + 1)
214 1
		*(octet*)dest = hexToO(src -= 2);
215
}

Read our documentation on viewing source code .

Loading