]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
lib/util: Speed up slow data-blob-to-hex functions
authorJo Sutton <josutton@catalyst.net.nz>
Wed, 1 Mar 2023 01:50:45 +0000 (14:50 +1300)
committerDouglas Bagnall <dbagnall@samba.org>
Wed, 28 Aug 2024 04:24:39 +0000 (04:24 +0000)
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 <josutton@catalyst.net.nz>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
lib/util/data_blob.c
lib/util/samba_util.h

index b5b78bc7a8a30c0990cd305f71a6dd13e2cf35a5..470aa67cc61c67c89bc54b28115077c9595c3cbc 100644 (file)
@@ -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;
index 81e6b6f9c39edbe6ec4ef4097965e73c0d710ddf..a38cc8a92f20376ddfcd893bd809e22d5b8f6d63 100644 (file)
@@ -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_ */