Gitのsha1ハッシュ値計算をC言語で実装してみた

Gitのsha1ハッシュ値計算をC言語で実装してみました。

仕様

$ echo -n "hello\n" | git hash-object --stdin
ce013625030ba8dba906f756967f9e9ca394464a
このコマンドがやっているのはblobオブジェクトのハッシュ値計算で、実際には"blob 6\0hello\n"という文字列をハッシュ化しています。
gitコマンドを使わずにopensslコマンドで算出することもできます。
$ echo -n "blob 6\0hello\n" | openssl sha1
(stdin)= ce013625030ba8dba906f756967f9e9ca394464a
さてこれをC言語書いてみました。

C言語によるsha1ハッシュ値計算

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/sha.h>

char *sha1_to_hex(const unsigned char *sha1)
{
    static int bufno;
    static char hexbuffer[4][50];
    static const char hex[] = "0123456789abcdef";
    char *buffer = hexbuffer[3 & ++bufno], *buf = buffer;
    int i;

    for (i = 0; i < 20; i++) {
	unsigned int val = *sha1++;
	*buf++ = hex[val >> 4];
	*buf++ = hex[val & 0xf];
    }
    *buf = '\0';

    return buffer;
}

void calc_sha1(const char *body)
{
    char *type = "blob";
    int hdrlen;
    char hdr[256];
    unsigned char sha1[41];
    unsigned long len;
    SHA_CTX c;

    len = strlen(body);

    sprintf(hdr, "%s %ld", type, len);
    hdrlen = strlen(hdr) + 1;

    SHA1_Init(&c);
    SHA1_Update(&c, hdr, hdrlen);
    SHA1_Update(&c, body, len);
    SHA1_Final(sha1, &c);

    printf("%s\n", sha1_to_hex(sha1));
}

int main()
{
    char *body = "hello\n";
    calc_sha1(body);
    return 0;
}
ちなみにsha1_to_hex関数の方はgitのソースコードを丸パクリしただけです。:)
私が自分の頭で考えて書いたのはcalc_sha1関数の方です。

実行結果

$ gcc -g -Wall -lssl calc_sha1.c -o calc_sha1
$ ./calc_sha1
ce013625030ba8dba906f756967f9e9ca394464a
で、できた!!
やった~~~~!!!
カテゴリ:

人気記事