add hex_decode

This commit is contained in:
Evan Burkey 2024-03-28 18:30:27 -07:00
parent 360fb91e06
commit cf6d3ce892
4 changed files with 58 additions and 5 deletions

View File

@ -22,3 +22,22 @@ in case you need to know the size of the decoded data, otherwise you can just pa
```c ```c
unsigned char *b64_decode(const char *s, size_t sz, size_t *decode_sz); unsigned char *b64_decode(const char *s, size_t sz, size_t *decode_sz);
``` ```
### hex_decode
Decodes a string of characters representing hexadecimal bytes into an array of `unsigned char`.
For example, converts `"DEADBEEF"` into `[0xDE, 0xAD, 0xBE, 0xEF]`.
```c
unsigned char *hex_decode(const char *orig, size_t *sz);
// Example
s = hex_decode("DEADBEEF", &s_sz);
unsigned char h[4] = {
0xDE, 0xAD, 0xBE, 0xEF
};
for (size_t i = 0; i < 4; ++i) {
assert(s[i] == h[i]);
}
free(s);
```

View File

@ -3,7 +3,8 @@
#include <stddef.h> #include <stddef.h>
char *b64_encode(const unsigned char *s, size_t sz); unsigned char *b64_encode(const unsigned char *s, size_t sz);
unsigned char *b64_decode(const char *s, size_t sz, size_t *decode_sz); unsigned char *b64_decode(const char *s, size_t sz, size_t *decode_sz);
unsigned char *hex_decode(const char *orig, size_t *sz);
#endif // LIBFLINT_CRYPTO_H #endif // LIBFLINT_CRYPTO_H

View File

@ -1,6 +1,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <ctype.h> #include <ctype.h>
#include <stdio.h>
#include "lfcrypto.h" #include "lfcrypto.h"
@ -18,7 +19,7 @@ static const char b64_table[] = {
}; };
typedef struct { typedef struct {
char *ptr; unsigned char *ptr;
int count; int count;
} b64_buf; } b64_buf;
@ -44,7 +45,7 @@ static int resize_b64_buf(b64_buf *b, size_t sz) {
return 0; return 0;
} }
char *b64_encode(const unsigned char *s, size_t sz) { unsigned char *b64_encode(const unsigned char *s, size_t sz) {
int i = 0; int i = 0;
b64_buf encbuf; b64_buf encbuf;
size_t size = 0; size_t size = 0;
@ -198,5 +199,28 @@ unsigned char *b64_decode(const char *s, size_t sz, size_t *decode_sz) {
*decode_sz = size; *decode_sz = size;
} }
return (unsigned char*)decbuf.ptr; return decbuf.ptr;
}
unsigned char *hex_decode(const char *orig, size_t *sz) {
size_t buf_sz = strlen(orig) + 1;
if (strlen(orig) % 2 != 0) {
buf_sz += 1;
}
char *buf = malloc(sizeof(char) * buf_sz);
strcpy(buf, orig);
buf[buf_sz - 1] = '\0';
*sz = buf_sz / 2;
unsigned char *hex = malloc(sizeof(unsigned char) * *sz);
const char *pos = buf;
for (size_t i = 0; i < *sz; ++i) {
sscanf(pos, "%2hhx", &hex[i]);
pos += 2;
}
free(buf);
return hex;
} }

View File

@ -311,7 +311,7 @@ void test_string() {
void test_crypto() { void test_crypto() {
char *in = "BUTT"; char *in = "BUTT";
char *s = b64_encode(in, strlen(in)); unsigned char *s = b64_encode(in, strlen(in));
assert(strcmp(s, "QlVUVA==") == 0); assert(strcmp(s, "QlVUVA==") == 0);
free(s); free(s);
@ -326,6 +326,15 @@ void test_crypto() {
assert(strcmp(s, "a longer base64 test, apparently") == 0); assert(strcmp(s, "a longer base64 test, apparently") == 0);
assert(strlen(s) == s_sz); assert(strlen(s) == s_sz);
free(s); free(s);
s = hex_decode("DEADBEEF", &s_sz);
unsigned char h[4] = {
0xDE, 0xAD, 0xBE, 0xEF
};
for (size_t i = 0; i < 4; ++i) {
assert(s[i] == h[i]);
}
free(s);
} }
#if defined(__APPLE__) || defined(__MACH__) #if defined(__APPLE__) || defined(__MACH__)