プログラミングのメモ帳(C/C++/HSP)

日々のプログラミングで気づいた点や小技集を紹介します。(Windows 10/XP/Vista、VC2017、HSP)

ファイルのMD2/MD4/MD5ハッシュの計算(128ビット)

2008年05月15日 12時16分00秒 | アルゴリズム関連

ファイルのMD2/MD4/MD5ハッシュの計算は次の手順で行えます。(戻る)

  1. 鍵コンテナの取得(CryptAcquireContext)
  2. ハッシュ値の生成(CryptCreateHash)
  3. ファイルを開く(fopen)
  4. 1行ずつ読み込む(fgets)
  5. ハッシュ値の追加(CryptHashData)
  6. ファイルの最後まで(4)へ移動して繰り返す
  7. ハッシュ値の取得(CryptGetHashParam)
  8. ファイルを閉じる(fclose)
  9. ハッシュ値の破棄(CryptDestroyHash)
  10. 鍵コンテナの破棄(CryptReleaseContext)

プロトタイプ宣言

BOOL CryptAcquireContext(
    HCRYPTPROV*     phProv,
    LPCTSTR         pszContainer,
    LPCTSTR         pszProvider,
    DWORD           dwProvType,
    DWORD           dwFlags
);

BOOL CryptReleaseContext(
    HCRYPTPROV      hProv,
    DWORD           dwFlags
);

BOOL CryptCreateHash(
    HCRYPTPROV      hProv,
    ALG_ID          Algid,
    HCRYPTKEY       hKey,
    DWORD           dwFlags,
    HCRYPTHASH*     phHash
);

BOOL CryptDestroyHash(
    HCRYPTHASH      hHash
);

BOOL CryptHashData(
    HCRYPTHASH      hHash,
    BYTE*           pbData,
    DWORD           dwDataLen,
    DWORD           dwFlags
);

BOOL CryptGetHashParam(
    HCRYPTHASH      hHash,
    DWORD           dwParam,
    BYTE*           pbData,
    DWORD*          pdwDataLen,
    DWORD           dwFlags
);

使い方

#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <wincrypt.h>

// マクロ関数
#define getFileMD2(s,hash)  getFileHash(s,hash,CALG_MD2)
#define getFileMD4(s,hash)  getFileHash(s,hash,CALG_MD4)
#define getFileMD5(s,hash)  getFileHash(s,hash,CALG_MD5)

// ファイルのMD2/MD4/MD5コードを計算
extern bool getFileHash( const char file[], char hash[16], ALG_ID algID )
{
    bool         bRet = false;
    HCRYPTPROV  hProv = NULL;   // 鍵コンテナ
    HCRYPTHASH  hHash = NULL;   // ハッシュ・オブジェクト
    LPBYTE      pbHash = (LPBYTE)hash;
    DWORD       dwHashLen = 16;
    
    ZeroMemory( pbHash, dwHashLen );
    
    if ( CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET) ){
        if ( CryptCreateHash(hProv,algID,0,0,&hHash) ){
            char    buff[ 64 * 1024 ];
            size_t  size;
            FILE    *fp;
            
            if ( (fp = fopen(file,"rb")) != NULL ){
                while ( (size = fread(buff,1,sizeof(buff),fp)) != 0 ){
                    bRet = CryptHashData(hHash,(LPBYTE)buff,(DWORD)size,0) ? true : false;
                    if ( bRet ) break;
                }
                if ( bRet ){
                    CryptGetHashParam( hHash, HP_HASHVAL, pbHash, &dwHashLen, 0 );
                }
                fclose( fp );
            }
            CryptDestroyHash( hHash );
        }
        CryptReleaseContext( hProv, 0 );
    }
    return bRet;
}

// メイン関数
int main( void )
{
    char  hash[ 16 ];
    char  file[ 256 ];
    char *find;
    
    while ( fgets(file,sizeof(file),stdin) != NULL ){
        if ( (find = strchr(file,'\n')) != NULL ){
            *find = '\0';
        }
        if ( getFileMD5(file,hash) ){
            for ( int i = 0 ; i < 16 ; i++ ){
                printf( "%02X", (BYTE)hash[i] );
            }
            printf( ":%s\n", file );
        }
    }
    return 0;
}
  • ファイル名をフルパスで入力します。
  • またはパイプやリダイレクションを利用して入力させます。
  • 出力は128ビットの16進32桁とフルパス名が標準出力に表示されます。

関連記事



コメント    この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« MD2/MD4/MD5ハッシュの計算(1... | トップ | CD/DVDトレイを開ける/閉める »
最新の画像もっと見る

コメントを投稿

アルゴリズム関連」カテゴリの最新記事