From 6b6413da9326944478d0418a31d759a2962a67e8 Mon Sep 17 00:00:00 2001 From: Jo Sutton Date: Wed, 1 Mar 2023 14:50:45 +1300 Subject: [PATCH] lib/util: Speed up slow data-blob-to-hex functions This is much faster than calling sprintf() for every byte of data, and improves the performance of functions outputting binary DNs. Signed-off-by: Jo Sutton Reviewed-by: Douglas Bagnall --- lib/util/data_blob.c | 12 ++++++---- lib/util/samba_util.h | 52 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/lib/util/data_blob.c b/lib/util/data_blob.c index b5b78bc7a8a..470aa67cc61 100644 --- a/lib/util/data_blob.c +++ b/lib/util/data_blob.c @@ -171,8 +171,10 @@ _PUBLIC_ char *data_blob_hex_string_lower(TALLOC_CTX *mem_ctx, const DATA_BLOB * /* this must be lowercase or w2k8 cannot join a samba domain, as this routine is used to encode extended DNs and windows only accepts lowercase hexadecimal numbers */ - for (i = 0; i < blob->length; i++) - slprintf(&hex_string[i*2], 3, "%02x", blob->data[i]); + for (i = 0; i < blob->length; i++) { + hex_string[i * 2] = nybble_to_hex_lower(blob->data[i] >> 4); + hex_string[i * 2 + 1] = nybble_to_hex_lower(blob->data[i]); + } hex_string[(blob->length*2)] = '\0'; return hex_string; @@ -188,8 +190,10 @@ _PUBLIC_ char *data_blob_hex_string_upper(TALLOC_CTX *mem_ctx, const DATA_BLOB * return NULL; } - for (i = 0; i < blob->length; i++) - slprintf(&hex_string[i*2], 3, "%02X", blob->data[i]); + for (i = 0; i < blob->length; i++) { + hex_string[i * 2] = nybble_to_hex_upper(blob->data[i] >> 4); + hex_string[i * 2 + 1] = nybble_to_hex_upper(blob->data[i]); + } hex_string[(blob->length*2)] = '\0'; return hex_string; diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h index 81e6b6f9c39..a38cc8a92f2 100644 --- a/lib/util/samba_util.h +++ b/lib/util/samba_util.h @@ -650,4 +650,56 @@ struct tevent_context *samba_tevent_context_init(TALLOC_CTX *mem_ctx); */ void samba_tevent_set_debug(struct tevent_context *ev, const char *name); +static inline char nybble_to_hex_lower(uint8_t val) +{ + uint8_t nybble = val & 0xf; + + switch (nybble) { + case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: + case 0x5: case 0x6: case 0x7: case 0x8: case 0x9: + return '0' + nybble; + case 0xa: + return 'a'; + case 0xb: + return 'b'; + case 0xc: + return 'c'; + case 0xd: + return 'd'; + case 0xe: + return 'e'; + case 0xf: + return 'f'; + } + + /* unreachable */ + return '\0'; +} + +static inline char nybble_to_hex_upper(uint8_t val) +{ + uint8_t nybble = val & 0xf; + + switch (nybble) { + case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: + case 0x5: case 0x6: case 0x7: case 0x8: case 0x9: + return '0' + nybble; + case 0xa: + return 'A'; + case 0xb: + return 'B'; + case 0xc: + return 'C'; + case 0xd: + return 'D'; + case 0xe: + return 'E'; + case 0xf: + return 'F'; + } + + /* unreachable */ + return '\0'; +} + #endif /* _SAMBA_UTIL_H_ */