0

16 進数値の文字列を返す関数を実装しようとしています。この関数を使用して 16 進値を出力します。

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

これは、いくつかの16進値を出力します。71c092a79cf30c4c7e7baf46a4af3c78cedec9ae3867d1e2600ffc39d58beaf2

文字列を返すようにこの関数を変更するにはどうすればよいですか? すなわち

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

(目標は、後で2つの値を比較することです)

4

4 に答える 4

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

free明らかに、呼び出し元は返された文字列を処理する責任があります。

それでも、@ K-Balloが彼の答えで正しく言ったように、それらを比較するために2つのハッシュを文字列形式に変換する必要はありません.その場合に必要なのは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;
}
于 2011-10-09T17:29:22.913 に答える
4

文字列を返すようにこの関数を変更するにはどうすればよいですか?

を使用して文字列変数に出力できますsprintf。ハッシュサイズは固定されていると仮定しているので、文字列のサイズはnumber-of-chars-in-hash * 2 + 1. その情報を返す方法は C の典型的な問題ですmalloc。ユーザーが覚えておく必要がある ed 文字列を返すかfree、次の関数呼び出しで置き換えられる静的文字列を返すことができます (そして関数を非再入可能)。char*個人的には、関数に目的地とサイズを持たせる代わりに、文字列を返すことを避ける傾向があります。

(目標は、後で2つの値を比較できるようにすることです)

2 つのハッシュ変数を生の形式で比較するだけです。そのための文字列は必要ありません。

于 2011-10-09T17:31:16.237 に答える
2

このsprintf()関数は と同じことを行いますがprintf()、char バッファーに「出力」する点が異なります。これにより、関数は次のようになります。

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

于 2011-10-09T17:31:19.100 に答える
0

ユーザーに、書き込み先のバッファーとサイズを渡すように指示します。明らかに、関数の名前を変更する必要があります。これも少し一般的です。おそらくパラメーターが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()

于 2011-10-09T17:47:00.840 に答える