md5 — 文字列のMD5ハッシュを計算

PHP
  • カテゴリ: PHP
  • 掲載バージョン: PHP 8.4
  • 名前空間 / FQCN / コマンド: md5
  • 関連: hash / md5_file / hash_equals / password_hash / hash_hmac
  • 変更履歴: 主要な仕様変更は近年なし(PHP 8系で型の厳格化により不正型で TypeError

要点(TL;DR)

  • 任意の文字列から32桁の16進(または16バイト生)MD5ハッシュを得る
  • 最低限の使い方:$hex = md5('hello');
  • よくある罠
    • パスワード用途禁止(衝突耐性が弱い/総当たりに脆弱)→ password_hash() を使う
    • $binary = true生バイト(NULL含む)→ そのまま表示・保存で壊れやすい
    • 入力はバイト列として扱われる→ 文字コード差異で結果が変わる

概要

md5() は入力文字列の MD5 ダイジェストを返します。結果は既定で32桁の小文字16進です。軽量な重複検出やキャッシュキー作成など非セキュア用途には使えますが、整合性検証や署名、特にパスワード保存などセキュリティが関わる用途には不適です。より安全な hash('sha256', ...)password_hash() を選びましょう。

構文 / シグネチャ

string md5(string $string, bool $binary = false)

引数(表)

引数必須既定値説明
$stringstringハッシュ化する文字列(バイト列として扱う)
$binaryboolfalsetrue で16バイトのダイジェストを返す(NULLバイト含む)
  • 戻り値string$binary=false なら 32桁16進、小文字/$binary=true なら 16バイト)
  • 例外/副作用:不正型(配列など)で TypeError$binary=true の戻りはバイナリを含み、画面出力やJSON化で不具合になり得る。

使用例

最小例

<?php
$hash = md5('hello'); // "5d41402abc4b2a76b9719d911017c592"
echo $hash . PHP_EOL;

実務例(非セキュア用途のキャッシュキー生成)

<?php
// APIレスポンスのパラメータから安価なキーを作る(機密・改ざん検知には使わない)
$params = ['page' => 2, 'q' => 'laravel md5', 'lang' => 'ja'];
$key = 'cache:search:' . md5(json_encode($params, JSON_UNESCAPED_UNICODE));

// 値の保存
$value = ['items' => [1,2,3], 'fetched_at' => time()];
file_put_contents(sys_get_temp_dir() . "/{$key}.json", json_encode($value));

バイナリ出力の扱い

<?php
$raw = md5('hello', true);          // 16バイトの生データ
$store = base64_encode($raw);       // 文字列保存したい場合はエンコード
echo $store . PHP_EOL;              // "XUEQKrxLKna5cZ2REBfFkg=="

多バイト文字の注意(文字コード差異で結果が変わる)

<?php
$str = 'あ'; // UTF-8 を前提
$hashUtf8 = md5($str);
$hashSjis = md5(mb_convert_encoding($str, 'SJIS', 'UTF-8'));
echo $hashUtf8 . PHP_EOL; // 8c0c3027e3cfc3d644caab3847a505b0
echo $hashSjis . PHP_EOL; // 文字コードが違えば別値

よくある落とし穴・注意

  • セキュリティ用途に不適:衝突が現実的。パスワードは password_hash()、整合性・署名は hash('sha256') 以上や HMAC/公開鍵を使用。
  • バイナリ戻り値$binary=true はNULLバイト含むため、DBの文字列カラムやJSONに直接入れない。bin2hex()base64_encode()で変換。
  • 改行・行末差"abc""abc\n" は別。CLIの md5sum と比較する際は行末(LF/CRLF)差異に注意。
  • 入力型:配列などを渡すと TypeError。常に文字列へ変換してから渡す。

代替・関連APIとの比較

  • hash('sha256', $s):強度・汎用性はこちらが上。整合性検証や署名ベースで使うなら SHA-256 以上を選ぶ。
  • password_hash($pass, PASSWORD_DEFAULT)パスワード専用。ソルト付与・ストレッチ込み。md5()の出番は無い。
  • hash_equals($a, $b):ハッシュ比較でタイミング攻撃を避ける。単純な === 比較より安全。
  • md5_file($path):ファイルのMD5。軽量な重複検出には可。ただし信頼性の必要な整合性検証は hash_file('sha256', ...) を推奨。

テスト例(Pest)

<?php

it('makes 32-char lowercase hex by default', function () {
    expect(md5('hello'))->toBe('5d41402abc4b2a76b9719d911017c592');
    expect(strlen(md5('hello')))->toBe(32);
});

it('returns 16 bytes when binary=true', function () {
    $raw = md5('hello', true);
    expect(strlen($raw))->toBe(16);
});

it('depends on encoding (UTF-8 vs others)', function () {
    $utf8 = md5('あ'); // UTF-8 前提
    expect($utf8)->toBe('8c0c3027e3cfc3d644caab3847a505b0');
});

トラブルシュート(エラー別)

症状/エラー原因対処
画面に「文字化け」や表示崩れ$binary=true で生バイトをそのまま出力bin2hex($raw)base64_encode($raw) で可視化
CLI の md5sum と値が合わない入力末尾の改行/改行コード(LF/CRLF)が異なる行末を揃える、rtrim($s, "\r\n") で統一
静的解析やセキュリティ診断で指摘MD5の脆弱性(衝突・総当たり)用途を見直し、password_hash() / hash('sha256') / HMAC等へ置換
TypeError が発生配列・オブジェクトを直接渡している明示的に string 化((string)$valuejson_encode() など)

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする