From 341fcb5192bf89436681566074087a4b25bafadb Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sat, 21 Jul 2007 12:57:12 +0000 Subject: [PATCH] Added silc_hex2data and silc_data2hex. --- lib/silcutil/silcutil.c | 58 +++++++++++++++++++++++++++ lib/silcutil/silcutil.h | 32 +++++++++++++++ lib/silcutil/tests/test_silcstrutil.c | 16 +++++++- 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index 5cd09db0..0333e630 100644 --- a/lib/silcutil/silcutil.c +++ b/lib/silcutil/silcutil.c @@ -630,3 +630,61 @@ void silc_hexdump(const unsigned char *data, SilcUInt32 data_len, break; } } + +/* Convert hex string to data. Each hex number must have two characters. */ + +SilcBool silc_hex2data(const char *hex, unsigned char *data, + SilcUInt32 data_size, SilcUInt32 *ret_data_len) +{ + char *cp = (char *)hex; + unsigned char l, h; + int i; + + if (data_size < strlen(hex) / 2) + return FALSE; + + for (i = 0; i < strlen(hex) / 2; i++) { + h = *cp++; + l = *cp++; + + h -= h < 'A' ? '0' : 'A' - 10; + l -= l < 'A' ? '0' : 'A' - 10; + + data[i] = (h << 4) | (l & 0xf); + } + + if (ret_data_len) + *ret_data_len = i; + + SILC_LOG_HEXDUMP(("len %d", i), data, i); + + return TRUE; +} + +/* Converts binary data to HEX string */ + +SilcBool silc_data2hex(const unsigned char *data, SilcUInt32 data_len, + char *hex, SilcUInt32 hex_size) +{ + unsigned char l, h; + char *cp = hex; + int i; + + if (hex_size - 1 < data_len * 2) + return FALSE; + + memset(hex, 0, hex_size); + + for (i = 0; i < data_len; i++) { + l = data[i]; + h = l >> 4; + l &= 0xf; + + *cp++ = h + (h > 9 ? 'A' - 10 : '0'); + *cp++ = l + (l > 9 ? 'A' - 10 : '0'); + } + + SILC_LOG_DEBUG(("HEX string: '%s'", hex)); + + return TRUE; +} diff --git a/lib/silcutil/silcutil.h b/lib/silcutil/silcutil.h index c6b0d43f..300c0a43 100644 --- a/lib/silcutil/silcutil.h +++ b/lib/silcutil/silcutil.h @@ -449,4 +449,36 @@ char *silc_get_real_name(); void silc_hexdump(const unsigned char *data, SilcUInt32 data_len, FILE *output); +/****f* silcutil/SilcUtilAPI/silc_hex2data + * + * SYNOPSIS + * + * SilcBool silc_hex2data(const char *hex, unsigned char *data, + * SilcUInt32 data_size, SilcUInt32 *ret_data_len); + * + * DESCRIPTION + * + * Converts HEX character string to binary data. Each HEX numbers must + * have two characters in the `hex' string. + * + ***/ +SilcBool silc_hex2data(const char *hex, unsigned char *data, + SilcUInt32 data_size, SilcUInt32 *ret_data_len); + +/****f* silcutil/SilcUtilAPI/silc_data2hex + * + * SYNOPSIS + * + * SilcBool silc_data2hex(const unsigned char *data, SilcUInt32 data_len, + * char *hex, SilcUInt32 hex_size); + * + * DESCRIPTION + * + * Converts binary data to HEX string. This NULL terminates the `hex' + * buffer automatically. + * + ***/ +SilcBool silc_data2hex(const unsigned char *data, SilcUInt32 data_len, + char *hex, SilcUInt32 hex_size); + #endif /* !SILCUTIL_H */ diff --git a/lib/silcutil/tests/test_silcstrutil.c b/lib/silcutil/tests/test_silcstrutil.c index 0673199e..d8bef756 100644 --- a/lib/silcutil/tests/test_silcstrutil.c +++ b/lib/silcutil/tests/test_silcstrutil.c @@ -53,9 +53,12 @@ int main(int argc, char **argv) { SilcBool success = FALSE; unsigned char *s1, *s2, *s3, *s4; - int l, opt; + unsigned char t[16]; + char h[32 + 1]; + int l, opt, i; + SilcUInt32 len; - while ((opt = getopt(argc, argv, "hVd")) != EOF) { + while ((opt = getopt(argc, argv, "hVd:")) != EOF) { switch(opt) { case 'h': printf("usage: test_silcstrutil\n"); @@ -162,6 +165,15 @@ int main(int argc, char **argv) goto err; SILC_LOG_DEBUG(("Regex not found (Ok)")); + /* HEX to data, data to HEX tests */ + for (i = 0; i < sizeof(t); i++) + t[i] = i; + silc_data2hex(t, sizeof(t), h, sizeof(h)); + silc_hex2data(h, t, sizeof(t), &len); + silc_snprintf(h, sizeof(h), "010203ffabdef9ab"); + silc_hex2data(h, t, sizeof(t), &len); + silc_data2hex(t, sizeof(t), h, sizeof(h)); + success = TRUE; err: -- 2.24.0