Skip to content

Commit 8b26fbd

Browse files
committed
Add chex
1 parent 8c4cc4d commit 8b26fbd

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

src/hex/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# chex
2+
3+
[chex.h](chex.h) file implement hex encoding/decoding basic functions by Tero 'stedo' Liukko under a MIT license. https://github.com/stedonet/chex

src/hex/chex.h

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2022 Tero 'stedo' Liukko. https://github.com/stedonet/chex
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
*/
24+
25+
#ifndef STEDO_CHEX_H
26+
#define STEDO_CHEX_H
27+
28+
/**
29+
* @brief check whether given ASCII character is a hexadecimal digit
30+
* @param[in] h ASCII character to decode
31+
* @return TRUE if h is hexadecimal, FALSE otherwise
32+
**/
33+
#pragma GCC diagnostic push
34+
#pragma GCC diagnostic ignored "-Wunused-function"
35+
static unsigned chex_isxdigit(unsigned h){
36+
unsigned char n09 = h - '0';
37+
unsigned char nAF = (h | 0x20) - 'a';
38+
return (n09 <= (9 - 0)) || (nAF <= (0xf - 0xa));
39+
}
40+
#pragma GCC diagnostic pop
41+
42+
/**
43+
* @brief encode nibble to hexadecimal ASCII character
44+
* @param[in] nibble value to encode
45+
* @return hexadecimal ASCII value
46+
* @note the four most significant bits are ignored
47+
**/
48+
static char chex_toxdigit(unsigned nibble){
49+
const char* lut = "0123456789abcdef";
50+
return lut[nibble & 0xf];
51+
}
52+
53+
54+
/**
55+
* @brief decode a single case-insensitive hexadecimal ASCII character to its decimal value
56+
* @param[in] h ASCII character to decode
57+
* @return decimal value of the input
58+
* @note the input is assumed to be a valid
59+
**/
60+
static unsigned char chex_fromxdigit(unsigned h){
61+
return ((h & 0xf) + (h >> 6) * 9);
62+
}
63+
64+
65+
/**
66+
* @brief encode an array of bytes to an array of hexadecimal ASCII characters
67+
* @param[out] hex buffer to write to
68+
* @param[in] hlen maximum number of characters to write
69+
* @param[in] bin array of bytes to encode
70+
* @param[in] blen number of bytes to encode
71+
* @return number of characters written
72+
* @note null terminator is not included in the output
73+
**/
74+
static unsigned chex_encode(char* hex, unsigned hlen, const void* bin, unsigned blen){
75+
const unsigned char* b = (const unsigned char*)bin;
76+
unsigned i, j;
77+
for(i = 0, j = 0; (i < blen) && (j+1 < hlen); ++i, j+=2){
78+
hex[j+0] = chex_toxdigit(b[i]>>4);
79+
hex[j+1] = chex_toxdigit(b[i]>>0);
80+
}
81+
return j;
82+
}
83+
84+
85+
/**
86+
* @brief decode an array of hexadecimal ASCII characters to an array of bytes
87+
* @param[out] bin buffer to write to
88+
* @param[in] blen maximum number of bytes to write
89+
* @param[in] hex array of hex characters to decode
90+
* @param[in] hlen number of hex characters to decode
91+
* @return number of bytes written
92+
* @note hex input is assumed valid and its length a multiple of two
93+
**/
94+
static unsigned chex_decode(void* bin, unsigned blen, const char* hex, unsigned hlen){
95+
unsigned i, j;
96+
for(i = 0, j = 0; (i < blen) && (j+1 < hlen); ++i, j+=2){
97+
unsigned char hi = chex_fromxdigit(hex[j+0]);
98+
unsigned char lo = chex_fromxdigit(hex[j+1]);
99+
((unsigned char*)bin)[i] = (hi << 4) | lo;
100+
}
101+
return i;
102+
}
103+
104+
#endif /* STEDO_CHEX_H */

0 commit comments

Comments
 (0)