aboutsummaryrefslogtreecommitdiff
path: root/hex.c
diff options
context:
space:
mode:
Diffstat (limited to 'hex.c')
-rw-r--r--hex.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/hex.c b/hex.c
new file mode 100644
index 0000000..61cf55f
--- /dev/null
+++ b/hex.c
@@ -0,0 +1,49 @@
+#include "hex.h"
+#include <errno.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int hex_encode(const void *const b, char *hex, const size_t buflen,
+ size_t hexlen)
+{
+ const char *buf = b;
+
+ for (size_t i = 0; i < buflen; i++)
+ {
+ const int r = snprintf(hex, hexlen, "%02hhx", *(const char *)buf++);
+
+ if (r < 0 || r >= hexlen)
+ return -1;
+
+ hexlen -= r;
+ hex += 2;
+ }
+
+ return 0;
+}
+
+int hex_decode(const char *const hex, void *const b, size_t n)
+{
+ unsigned char *buf = b;
+
+ for (const char *s = hex; *s; s += 2)
+ {
+ const char nibble[sizeof "00"] = {*s, *(s + 1)};
+
+ if (!n)
+ return -1;
+
+ char *end;
+
+ errno = 0;
+ *buf++ = strtoul(nibble, &end, 16);
+
+ if (errno || *end)
+ return -1;
+
+ n--;
+ }
+
+ return n ? -1 : 0;
+}