在 C 中将十六进制值转换为 char 数组

发布于 2024-12-08 22:33:49 字数 512 浏览 0 评论 0原文

我正在尝试实现一个返回十六进制值字符串的函数。我使用此函数打印出十六进制值:

void print_hex(unsigned char *hash, const hashid type) {

    int i;
    for (i = 0; i < mhash_get_block_size(type); i++) {
        printf("%.2x", hex[i]);
    }
    printf("\n");
}

这会输出一些十六进制值,例如 71c092a79cf30c4c7e7baf46a4af3c78cedec9ae3867d1e2600ffc39d58beaf2

如何修改此函数以使其返回字符串?即

unsigned char *get_hash_str(unsigned char *hash, const hashid type) { /* ?? */ }

(目标是稍后比较这两个值)

I'm trying to implement a function which returns a string of hex values. I print the hex values out using this function:

void print_hex(unsigned char *hash, const hashid type) {

    int i;
    for (i = 0; i < mhash_get_block_size(type); i++) {
        printf("%.2x", hex[i]);
    }
    printf("\n");
}

This outputs some hex value, e.g. 71c092a79cf30c4c7e7baf46a4af3c78cedec9ae3867d1e2600ffc39d58beaf2

How can I modify this function so that it returns a string? i.e.

unsigned char *get_hash_str(unsigned char *hash, const hashid type) { /* ?? */ }

(The goal being to compare the 2 values later)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

享受孤独 2024-12-15 22:33:49
char * print_hex(const unsigned char *hash, const hashid type)
{
    const char lookupTable[]="0123456789abcdef";
    const size_t hashLength=mhash_get_block_size(type);
    size_t i;
    char * out=malloc(hashLength*2+1);
    if(out==NULL)
        return NULL;
    for (i = 0; i < hashLength; i++)
    {
        out[i*2]=lookupTable[hash[i]>>4];
        out[i*2+1]=lookupTable[hash[i]&0xf];
    }
    out[hashLength*2]=0;
    return out;
}

显然,调用者负责释放返回的字符串。

不过,正如 @K-Ballo 在他的回答中正确所说,您不需要将两个哈希值转换为字符串形式来比较它们,在这种情况下您所需要的只是一个 memcmp

int compare_hashes(const unsigned char * hash1, const hashid hash1type, const unsigned char * hash2, const hashid hash2type)
{
    if(hash1type!=hash2type)
        return 0;
    return memcmp(hash1, hash2, mhash_get_block_size(hash1type))==0;
}
char * print_hex(const unsigned char *hash, const hashid type)
{
    const char lookupTable[]="0123456789abcdef";
    const size_t hashLength=mhash_get_block_size(type);
    size_t i;
    char * out=malloc(hashLength*2+1);
    if(out==NULL)
        return NULL;
    for (i = 0; i < hashLength; i++)
    {
        out[i*2]=lookupTable[hash[i]>>4];
        out[i*2+1]=lookupTable[hash[i]&0xf];
    }
    out[hashLength*2]=0;
    return out;
}

Obviously the caller is responsible for freeing the returned string.

Still, as @K-Ballo correctly said in his answer, you don't need to convert to string form two hashes to compare them, all you need in that case is just a memcmp.

int compare_hashes(const unsigned char * hash1, const hashid hash1type, const unsigned char * hash2, const hashid hash2type)
{
    if(hash1type!=hash2type)
        return 0;
    return memcmp(hash1, hash2, mhash_get_block_size(hash1type))==0;
}
烟花肆意 2024-12-15 22:33:49

如何修改此函数以使其返回字符串?

您可以使用 sprintf 打印到字符串变量。我假设哈希大小是固定的,因此您知道字符串的大小将为 number-of-chars-in-hash * 2 + 1。如何返回该信息是 C 中的一个典型问题,您可以返回一个经过 malloc 分配的字符串,然后用户必须记住释放该字符串,或者返回一个静态字符串,该字符串将被下次调用该函数所替换(并使该函数不可重入)。就我个人而言,我倾向于避免返回字符串,而是让函数采用 char* 目标和大小。

(目标是我可以稍后比较这两个值)

只需比较原始形式的两个哈希变量,您不需要字符串。

How can I modify this function so that it returns a string?

You can print to a string variable using sprintf. I assume the hash size is fixed, so you know the size of your string would be number-of-chars-in-hash * 2 + 1. How to return that information is a typical problem in C, you can either return a malloced string that the user must then remember to free, or return a static string that will get replaced with the next call to the function (and makes the function non-reentrable). Personally I tend to avoid returning strings, instead having the function take a char* destination and a size.

(The goal being that I can compare the 2 values later)

Just compare the two hash variables in its raw form, you don't need strings for that.

二智少女 2024-12-15 22:33:49

sprintf() 函数与 printf() 执行相同的操作,只不过它“打印”到字符缓冲区。这样,您的函数可能如下所示:

void sprint_hex(char *outbuf, unsigned char *hash, const hashid type) {
    int i;
    for (i = 0; i < mhash_get_block_size(type); i++) {
        sprintf(outbuf, "%.2x", hex[i]);
        outbuf += 2;
    }
}

请注意,这假设适当大小的缓冲区作为 outbuf 传入。

The sprintf() function does the same thing as printf(), except that it "prints" to a char buffer. With that your function could look like this:

void sprint_hex(char *outbuf, unsigned char *hash, const hashid type) {
    int i;
    for (i = 0; i < mhash_get_block_size(type); i++) {
        sprintf(outbuf, "%.2x", hex[i]);
        outbuf += 2;
    }
}

Note that this assumes that a buffer of suitable size is passed in as outbuf.

五里雾 2024-12-15 22:33:49

让用户传入要写入的缓冲区及其大小。显然,该函数必须重命名。即使这有点通用;由于 hashid 参数,它可能应该是 format_hash_to_hex_string()

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 类型参数替换为简单的长度(然后您可以合理地假设程序员知道缓冲区长度必须至少是哈希长度的 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() 函数的一些调用。

Have the user pass in the buffer to be written to, along with the size. Obviously, the function has to be renamed. Even this is a bit generic; it should perhaps be format_hash_to_hex_string() because of the hashid parameter.

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;
}

Or, if you trust your users to provide a big enough buffer:

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]);
}

Or if you prefer bit twiddling (which probably is quicker than calling 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;
}

To justify the generic name, it would be better to replace the hashid type parameter with a simple length (and you could then reasonably assume that the programmer knows that the buffer length must be at least 2 times the hash length):

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';
}

This now is a general purpose function. And you could wrap it to specialize it for your hash formatting if you wanted to; the wrapper might save you writing a few calls to your mhash_get_block_size() function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文