2

私は C/C++ でハッシュを研究しており、Linux で md5sum コマンドを複製しようとしました。ソース コードを分析した結果、md5sum は md5 ライブラリの md5_stream に依存しているようです。md5.h ライブラリの md5_stream 関数を以下のコードに近似させました。実行時間は ~13 ~ 14 秒です。md5_stream 関数を直接呼び出そうとしましたが、13 ~ 14 秒かかりました。md5sum は 4 秒で実行されます。GNU の人々は、コードを高速化するために何をしましたか?

md5.h/md5.c コードは、CoreUtils ソース コードで入手できます。

#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>

#include <iostream>
#include <iomanip>
#include <fstream>
#include "md5.h"

#define BLOCKSIZE 32784

int main()
{
    FILE *fpinput, *fpoutput;

    if ((fpinput = fopen("/dev/sdb", "rb")) == 0) {
        throw std::runtime_error("input file doesn't exist");
    }

    struct md5_ctx ctx;
    size_t sum;

    char *buffer = (char*)malloc (BLOCKSIZE + 72);
    unsigned char *resblock = (unsigned char*)malloc (16);
    if (!buffer)
      return 1;

    md5_init_ctx (&ctx);
    size_t n;
    sum = 0;

    while (!ferror(fpinput) && !feof(fpinput)) {
        n = fread (buffer + sum, 1, BLOCKSIZE - sum, fpinput);
        if (n == 0){
            break;
        }
        sum += n;

        if (sum == BLOCKSIZE) {
            md5_process_block (buffer, BLOCKSIZE, &ctx);
            sum = 0;
        }
    }

    if (n == 0 && ferror (fpinput)) {
        free (buffer);
        return 1;
    }

    /* Process any remaining bytes.  */
    if (sum > 0){
      md5_process_bytes (buffer, sum, &ctx);
    }

    /* Construct result in desired memory.  */
    md5_finish_ctx (&ctx, resblock);
    free (buffer);

    for (int x = 0; x < 16; ++x){
        std::cout << std::setfill('0') << std::setw(2) << std::hex << static_cast<uint16_t>(resblock[x]);
        std::cout << " ";
    }
    std::cout << std::endl;
    free(resblock);
    return 0;
}

編集: Fedora 19 64 ビットのデフォルトの mkspec 問題でした。

4

2 に答える 2