# At a local mysql-5.1-bugteam repository of davi
3334 Davi Arnaut 2010-01-26
Bug#49491: Much overhead for MD5() and SHA1() on short strings
MySQL's hash functions MD5 and SHA relied on the somewhat slow
sprintf function to convert the digests to hex representations.
This patch replaces the sprintf with a specific and inline hex
conversion function.
Patch contributed by Jan Steemann.
@ sql/item_strfunc.cc
Add a hex conversion function.
modified:
sql/item_strfunc.cc
=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc 2010-01-13 04:16:36 +0000
+++ b/sql/item_strfunc.cc 2010-01-26 14:54:05 +0000
@@ -42,6 +42,7 @@ C_MODE_END
String my_empty_string("",default_charset_info);
+static void tohex(char *to, const char *str, uint len);
bool Item_str_func::fix_fields(THD *thd, Item **ref)
@@ -114,12 +115,7 @@ String *Item_func_md5::val_str(String *s
null_value=1;
return 0;
}
- sprintf((char *) str->ptr(),
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
- digest[0], digest[1], digest[2], digest[3],
- digest[4], digest[5], digest[6], digest[7],
- digest[8], digest[9], digest[10], digest[11],
- digest[12], digest[13], digest[14], digest[15]);
+ tohex((char *) str->ptr(), (const char*) digest, 16);
str->length((uint) 32);
return str;
}
@@ -160,15 +156,7 @@ String *Item_func_sha::val_str(String *s
if (!( str->alloc(SHA1_HASH_SIZE*2) ||
(mysql_sha1_result(&context,digest))))
{
- sprintf((char *) str->ptr(),
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\
-%02x%02x%02x%02x%02x%02x%02x%02x",
- digest[0], digest[1], digest[2], digest[3],
- digest[4], digest[5], digest[6], digest[7],
- digest[8], digest[9], digest[10], digest[11],
- digest[12], digest[13], digest[14], digest[15],
- digest[16], digest[17], digest[18], digest[19]);
-
+ tohex((char *) str->ptr(), (const char*) digest, SHA1_HASH_SIZE);
str->length((uint) SHA1_HASH_SIZE*2);
null_value=0;
return str;
@@ -3419,6 +3407,16 @@ static void tohex(char *to, uint from, u
}
}
+static void tohex(char *to, const char *str, uint len)
+{
+ const char *str_end= str + len;
+ for (; str != str_end; ++str)
+ {
+ *to++= _dig_vec_lower[((uchar) *str) >> 4];
+ *to++= _dig_vec_lower[((uchar) *str) & 0x0F];
+ }
+}
+
static void set_clock_seq_str()
{
uint16 clock_seq= ((uint)(my_rnd(&uuid_rand)*16383)) | UUID_VARIANT;
Attachment: [text/bzr-bundle] bzr/davi.arnaut@sun.com-20100126145405-svibxi37nxgdy1x3.bundle