Files
MultiPar/source/par1j/md5_1.c
2023-03-12 10:41:47 +09:00

224 lines
6.1 KiB
C

// md5_1.c
// Copyright : 2021-05-14 Yutaka Sawada
// License : GPL
#include <windows.h>
#include "common1.h"
#include "phmd5.h"
#include "md5_1.h"
// バイト配列の MD5 ハッシュ値を求める
void data_md5(
unsigned char *data_in, // ハッシュ値を求めるバイト配列
unsigned int data_len, // 入力バイト数
unsigned char *hash) // ハッシュ値 16バイト
{
PHMD5 ctx;
Phmd5Begin(&ctx);
Phmd5Process(&ctx, data_in, data_len);
Phmd5End(&ctx);
memcpy(hash, ctx.hash, 16);
}
// ファイルの MD5 ハッシュ値を求める
int file_md5(
wchar_t *file_name, // 表示するファイル名
HANDLE hFileRead, // ハッシュ値を求めるファイルのハンドル
unsigned __int64 file_size,
unsigned char *hash) // ハッシュ値 (16バイト)
{
unsigned char buf[IO_SIZE];
unsigned int rv, len;
unsigned int time_last;
unsigned __int64 file_left;
PHMD5 hash_ctx;
// ファイルの先頭に戻す
file_left = 0;
if (!SetFilePointerEx(hFileRead, *((PLARGE_INTEGER)&file_left), NULL, FILE_BEGIN))
return 1;
prog_last = -1; // 検証中のファイル名を毎回表示する
time_last = GetTickCount();
file_left = file_size;
Phmd5Begin(&hash_ctx); // 初期化
while (file_left > 0){
if (file_left < IO_SIZE){
len = (unsigned int)file_left;
} else {
len = IO_SIZE;
}
if (!ReadFile(hFileRead, buf, len, &rv, NULL) || (len != rv))
return 1;
file_left -= len;
// MD5 計算
Phmd5Process(&hash_ctx, buf, len);
// 経過表示
if (GetTickCount() - time_last >= UPDATE_TIME){
if (print_progress_file((int)(((file_size - file_left) * 1000) / file_size), file_name))
return 2;
time_last = GetTickCount();
}
}
Phmd5End(&hash_ctx); // 最終処理
memcpy(hash, hash_ctx.hash, 16);
return 0;
}
// ファイルの MD5 ハッシュ値を求めて、全体的な経過を表示する
int file_md5_total(
HANDLE hFileRead, // ハッシュ値を求めるファイルのハンドル
unsigned __int64 file_size,
unsigned char *hash, // (16)
unsigned char *hash16, // 先頭 16KB 分のハッシュ値
__int64 total_file_size,
__int64 *prog_now) // 経過表示での現在位置
{
unsigned char buf[IO_SIZE];
unsigned int rv, len;
unsigned int time_last;
unsigned __int64 file_left;
PHMD5 hash_ctx;
// ファイルの先頭に戻す
file_left = 0;
if (!SetFilePointerEx(hFileRead, *((PLARGE_INTEGER)&file_left), NULL, FILE_BEGIN))
return 1;
time_last = GetTickCount() / UPDATE_TIME; // 時刻の変化時に経過を表示する
file_left = file_size;
Phmd5Begin(&hash_ctx); // 初期化
while (file_left > 0){
if (file_left < IO_SIZE){
len = (unsigned int)file_left;
} else {
len = IO_SIZE;
}
if (!ReadFile(hFileRead, buf, len, &rv, NULL) || (len != rv))
return 2;
(*prog_now) += len;
if (file_left == file_size){ // 最初だけ先頭 16KB 分のハッシュ値を計算する
if (len > 16384){
Phmd5Process(&hash_ctx, buf, 16384);
Phmd5End(&hash_ctx); // 最終処理
memcpy(hash16, hash_ctx.hash, 16);
Phmd5Begin(&hash_ctx); // 初期化しなおす
} else { // ファイル・サイズが 16KB 以下なら
Phmd5Process(&hash_ctx, buf, len);
Phmd5End(&hash_ctx); // 最終処理
memcpy(hash, hash_ctx.hash, 16);
return 0;
}
}
file_left -= len;
// MD5 計算
Phmd5Process(&hash_ctx, buf, len);
// 経過表示
if (GetTickCount() / UPDATE_TIME != time_last){
if (print_progress((int)(((*prog_now) * 1000) / total_file_size)))
return -2;
time_last = GetTickCount() / UPDATE_TIME;
}
}
Phmd5End(&hash_ctx); // 最終処理
memcpy(hash, hash_ctx.hash, 16);
return 0;
}
// ファイルの先頭 16KB 分の MD5 ハッシュ値を求める
int file_md5_16k(
HANDLE hFileRead, // ハッシュ値を求めるファイルのハンドル
unsigned __int64 file_size,
unsigned char *hash) // ハッシュ値 (16バイト)
{
unsigned char buf[16384];
unsigned int len;
LARGE_INTEGER qwi; // Quad Word Integer
PHMD5 hash_ctx;
// ファイルの先頭に戻す
qwi.QuadPart = 0;
if (!SetFilePointerEx(hFileRead, qwi, NULL, FILE_BEGIN))
return 1;
Phmd5Begin(&hash_ctx); // 初期化
if (!ReadFile(hFileRead, buf, 16384, &len, NULL))
return 2;
if ((unsigned __int64)len > file_size)
len = (unsigned int)file_size;
// MD5 計算
Phmd5Process(&hash_ctx, buf, len);
Phmd5End(&hash_ctx); // 最終処理
memcpy(hash, hash_ctx.hash, 16);
return 0;
}
// ファイルの先頭 32バイト目からの MD5 ハッシュ値を求める
int file_md5_from32(
wchar_t *file_name, // 表示するファイル名
HANDLE hFileRead, // ハッシュ値を求めるファイルのハンドル
unsigned char *hash) // ハッシュ値 (16バイト)
{
unsigned char buf[IO_SIZE];
unsigned int rv, len;
unsigned int time_last;
unsigned __int64 file_size, file_left;
LARGE_INTEGER qwi; // Quad Word Integer
PHMD5 hash_ctx;
// ファイル・サイズを取得する
if (!GetFileSizeEx(hFileRead, (PLARGE_INTEGER)&file_size))
return 1;
if (file_size <= 32)
return 1;
// ファイルの開始位置を 32バイト目にする
qwi.QuadPart = 32;
if (!SetFilePointerEx(hFileRead, qwi, NULL, FILE_BEGIN))
return 1;
prog_last = -1; // 検証中のファイル名を毎回表示する
time_last = GetTickCount();
file_left = file_size - 32;
Phmd5Begin(&hash_ctx); // 初期化
while (file_left > 0){
if (file_left < IO_SIZE){
len = (unsigned int)file_left;
} else {
len = IO_SIZE;
}
if (!ReadFile(hFileRead, buf, len, &rv, NULL) || (len != rv))
return 1;
file_left -= len;
// MD5 計算
Phmd5Process(&hash_ctx, buf, len);
// 経過表示
if (GetTickCount() - time_last >= UPDATE_TIME){
if (print_progress_file((int)(((file_size - file_left) * 1000) / file_size), file_name))
return 2;
time_last = GetTickCount();
}
}
Phmd5End(&hash_ctx); // 最終処理
memcpy(hash, hash_ctx.hash, 16);
return 0;
}