Пользователь должен передать в буфер для записи вместе с размером. Очевидно, что функция должна быть переименована. Даже это немного общего; возможно, оно должно быть format_hash_to_hex_string()
из-за параметра hashid
.
int format_hex_string(unsigned char const *hash, hashid type, char *buffer, size_t buflen)
{
size_t n = mhash_get_block_size(type);
if (buflen < 2 * n + 1)
return -1;
for (size_t i = 0; i < n; i++)
sprintf(&buffer[2*i], "%.2X", hash[i]);
return 0;
}
Или, если вы доверяете своим пользователям предоставить достаточно большой буфер:
format_hex_string(unsigned char const *hash, hashid type, char *buffer)
{
size_t n = mhash_get_block_size(type);
for (size_t i = 0; i < n; i++)
sprintf(&buffer[2*i], "%.2X", hash[i]);
}
Или, если вы предпочитаете битовое чередование (что, вероятно, быстрее, чем вызов sprintf()
):
int format_hex_string(unsigned char const *hash, hashid type, char *buffer, size_t buflen)
{
static char const hexdigits[] = "0123456789ABCDEF";
size_t n = mhash_get_block_size(type);
if (buflen < 2 * n + 1)
return -1;
for (size_t i = 0; i < n; i++)
{
*buffer++ = hexdigits[hash[i] >> 4];
*buffer++ = hexdigits[hash[i] & 0xF];
}
*buffer = '\0';
return 0;
}
Чтобы оправдать родовое имя, было бы лучше заменить параметр hashid type
простой длиной (и тогда вы могли бы разумно предположить, что программист знает, что длина буфера должна быть как минимум в 2 раза больше длины хеша):
int format_hex_string(unsigned char const *binbuffer, size_t binlen, char *hexbuffer)
{
static char const hexdigits[] = "0123456789ABCDEF";
for (size_t i = 0; i < binlen; i++)
{
*hexbuffer++ = hexdigits[binbuffer[i] >> 4];
*hexbuffer++ = hexdigits[binbuffer[i] & 0xF];
}
*hexbuffer = '\0';
}
Теперь это функция общего назначения. И вы можете обернуть его, чтобы специализировать его для форматирования вашего хэша, если хотите. Оболочка может сэкономить вам написание нескольких вызовов вашей функции mhash_get_block_size()
.