tools
読み取り中…
検索中…
一致する文字列を見つけられません
sha256.h
[詳解]
1#pragma once
2#include <filesystem>
3#include <sstream>
4#include <fstream>
5#include <iomanip>
6#include <filesystem>
7#include <vector>
8#include <openssl/evp.h>
9
10namespace fs = std::filesystem;
11
12/**
13 * @file sha256.h
14 * @brief SHA-256 ハッシュ計算ユーティリティ
15 *
16 * OpenSSL の EVP インターフェースを使用して、文字列またはファイルの
17 * SHA-256 ハッシュ値を 64 文字の小文字16進数文字列で返します。
18 */
19
20/**
21 * @brief 文字列の SHA-256 ハッシュ値を計算する
22 * @param data ハッシュを計算する入力文字列
23 * @return 64 文字の小文字16進数 SHA-256 ハッシュ文字列
24 * @throws std::runtime_error OpenSSL の初期化・計算に失敗した場合
25 */
26inline std::string sha256(const std::string& data) {
27 // OpenSSL初期化
28 EVP_MD_CTX* ctx = EVP_MD_CTX_new();
29 if (!ctx) {
30 throw std::runtime_error("EVP_MD_CTX_newに失敗");
31 }
32
33 const EVP_MD* md = EVP_sha256();
34 if (EVP_DigestInit_ex(ctx, md, nullptr) != 1) {
35 EVP_MD_CTX_free(ctx);
36 throw std::runtime_error("EVP_DigestInit_exに失敗");
37 }
38
39 // ハッシュ計算
40 if (EVP_DigestUpdate(ctx, data.data(), data.size()) != 1) {
41 EVP_MD_CTX_free(ctx);
42 throw std::runtime_error("EVP_DigestUpdateに失敗");
43 }
44
45 unsigned char hash[EVP_MAX_MD_SIZE];
46 unsigned int hashLength = 0;
47 if (EVP_DigestFinal_ex(ctx, hash, &hashLength) != 1) {
48 EVP_MD_CTX_free(ctx);
49 throw std::runtime_error("EVP_DigestFinal_exに失敗");
50 }
51
52 EVP_MD_CTX_free(ctx);
53
54 // 文字列化
55 std::ostringstream oss;
56 for (unsigned int i = 0; i < hashLength; ++i) {
57 oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(hash[i]);
58 }
59
60 return oss.str();
61}
62
63/**
64 * @brief ファイルの SHA-256 ハッシュ値を計算する
65 * @param filePath ハッシュを計算するファイルのパス
66 * @return 64 文字の小文字16進数 SHA-256 ハッシュ文字列。ファイルを開けない場合は "ERROR"
67 * @throws std::runtime_error OpenSSL の初期化・計算に失敗した場合
68 * @note ファイルは 8192 バイト単位でストリーム読み込みします
69 */
70inline std::string sha256f(const fs::path& filePath) {
71 std::ifstream file(filePath, std::ios::binary);
72 if (!file.is_open()) return "ERROR";
73
74 // OpenSSL初期化
75 EVP_MD_CTX* ctx = EVP_MD_CTX_new();
76 if (!ctx) {
77 throw std::runtime_error("EVP_MD_CTX_newに失敗");
78 }
79
80 const EVP_MD* md = EVP_sha256();
81 if (EVP_DigestInit_ex(ctx, md, nullptr) != 1) {
82 EVP_MD_CTX_free(ctx);
83 throw std::runtime_error("EVP_DigestInit_exに失敗");
84 }
85
86 // ハッシュ計算
87 std::vector<char> buffer(8192);
88 while (file) {
89 file.read(buffer.data(), buffer.size());
90 if (EVP_DigestUpdate(ctx, buffer.data(), file.gcount()) != 1) {
91 EVP_MD_CTX_free(ctx);
92 throw std::runtime_error("EVP_DigestUpdateに失敗");
93 }
94 }
95
96 unsigned char hash[EVP_MAX_MD_SIZE];
97 unsigned int hashLength = 0;
98 if (EVP_DigestFinal_ex(ctx, hash, &hashLength) != 1) {
99 EVP_MD_CTX_free(ctx);
100 throw std::runtime_error("EVP_DigestFinal_exに失敗");
101 }
102
103 EVP_MD_CTX_free(ctx);
104
105 // 文字列化
106 std::ostringstream oss;
107 for (unsigned int i = 0; i < hashLength; ++i) {
108 oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(hash[i]);
109 }
110
111 return oss.str();
112}
std::string sha256f(const fs::path &filePath)
ファイルの SHA-256 ハッシュ値を計算する
Definition sha256.h:70
std::string sha256(const std::string &data)
文字列の SHA-256 ハッシュ値を計算する
Definition sha256.h:26