Hash Identifier
ハッシュタイプを長さとフォーマットで識別 — MD5、SHA-1、SHA-256など
ハッシュ文字列
ハッシュ識別とは何か
ハッシュ識別とは、与えられたダイジェストがどの暗号ハッシュアルゴリズムによって生成されたかを特定するプロセスです。MD5、SHA-1、SHA-256 などの暗号ハッシュ関数はそれぞれ固定長の出力を生成し、その出力長が未知のハッシュを識別する際の主要な手がかりとなります。データベースダンプ、設定ファイル、または API レスポンスで16進数文字列を見かけた際、ハッシュ識別ツールはどのアルゴリズムが生成した可能性が高いかを教えてくれます。
すべてのハッシュアルゴリズムは、任意の入力データをダイジェストと呼ばれる固定サイズの出力にマップします。MD5 は常に128ビット(16進数32文字)、SHA-1 は常に160ビット(16進数40文字)、SHA-256 は常に256ビット(16進数64文字)を出力します。この決定論的な出力長こそが、元の入力やハッシュコードにアクセスせずともアルゴリズムの識別を可能にする仕組みです。
長さだけによる識別が必ずしも確定的とは限りません。複数のアルゴリズムが同じ出力サイズを持つ場合があります。例えば、SHA-256 と SHA3-256 はどちらも16進数64文字のダイジェストを生成します。このような場合、ハッシュ識別ツールは出現頻度順にランク付けされた候補アルゴリズムのリストを返します。ソースシステム、エンコード形式(hex か Base64 か)、またはアルゴリズムプレフィックスの有無(bcrypt の '$2b$' など)といったコンテキスト情報によって候補をさらに絞り込むことができます。
ハッシュ識別ツールを使う理由
不明なハッシュは、セキュリティ監査、データベース移行、フォレンジック調査の現場で日常的に登場します。ハッシュ識別ツールは推測作業を排除し、数秒で正しいアルゴリズムを特定します。
ハッシュ識別ツールのユースケース
ハッシュアルゴリズム長さ参照表
以下の表は、一般的なハッシュアルゴリズムとそのビット数・16進数文字数・生バイト数の対応を示しています。これはハッシュ識別ツールで使用される主要な参照テーブルです。複数のアルゴリズムが同じ16進数の長さを共有する場合は、識別のために追加のコンテキストが必要です。
| アルゴリズム | ビット | 16進数文字数 | バイト | 備考 |
|---|---|---|---|---|
| MD5 | 128 | 32 | 16 | Broken — collisions trivial since 2004 |
| SHA-1 | 160 | 40 | 20 | Deprecated — SHAttered attack (2017) |
| SHA-224 | 224 | 56 | 28 | Truncated SHA-256; rarely used standalone |
| SHA-256 | 256 | 64 | 32 | Current standard; TLS, Git, Bitcoin |
| SHA-384 | 384 | 96 | 48 | Truncated SHA-512; CNSA Suite approved |
| SHA-512 | 512 | 128 | 64 | Maximum SHA-2 output; large-data hashing |
| SHA3-256 | 256 | 64 | 32 | Keccak-based; NIST alternative to SHA-2 |
| SHA3-512 | 512 | 128 | 64 | Keccak-based; highest SHA-3 strength |
| RIPEMD-160 | 160 | 40 | 20 | Used in Bitcoin address derivation |
| BLAKE2s | 256 | 64 | 32 | Faster than SHA-256; 256-bit output |
ハッシュ長の曖昧さを解消する
一部の16進数の長さは複数のアルゴリズムに対応します。最も多い曖昧なケースは、64文字のハッシュ(SHA-256 対 SHA3-256)と40文字のハッシュ(SHA-1 対 RIPEMD-160)の2つです。長さだけでは不十分な場合に見分ける方法を以下に示します。
コード例
以下は、4つの言語における16進数の長さによるハッシュ識別の実装例です。各関数は16進数エンコードを検証し、文字数を参照して、一致するすべてのアルゴリズムを返します。
function identifyHash(hex) {
const len = hex.length
const isHex = /^[0-9a-fA-F]+$/.test(hex)
if (!isHex) return ['Not a hex-encoded hash']
const map = {
32: ['MD5'],
40: ['SHA-1', 'RIPEMD-160'],
56: ['SHA-224', 'SHA3-224'],
64: ['SHA-256', 'SHA3-256', 'BLAKE2s'],
96: ['SHA-384', 'SHA3-384'],
128: ['SHA-512', 'SHA3-512', 'BLAKE2b'],
}
return map[len] || [`Unknown (${len} hex chars)`]
}
identifyHash('d41d8cd98f00b204e9800998ecf8427e')
// → ["MD5"]
identifyHash('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855')
// → ["SHA-256", "SHA3-256", "BLAKE2s"]import re
HASH_LENGTHS = {
32: ['MD5'],
40: ['SHA-1', 'RIPEMD-160'],
56: ['SHA-224', 'SHA3-224'],
64: ['SHA-256', 'SHA3-256', 'BLAKE2s'],
96: ['SHA-384', 'SHA3-384'],
128: ['SHA-512', 'SHA3-512', 'BLAKE2b'],
}
def identify_hash(hex_string: str) -> list[str]:
hex_string = hex_string.strip()
if not re.fullmatch(r'[0-9a-fA-F]+', hex_string):
return ['Not a hex-encoded hash']
return HASH_LENGTHS.get(len(hex_string), [f'Unknown ({len(hex_string)} hex chars)'])
identify_hash('da39a3ee5e6b4b0d3255bfef95601890afd80709')
# → ['SHA-1', 'RIPEMD-160']
identify_hash('a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a')
# → ['SHA-256', 'SHA3-256', 'BLAKE2s']package main
import (
"fmt"
"regexp"
)
var hexPattern = regexp.MustCompile("^[0-9a-fA-F]+$")
var hashLengths = map[int][]string{
32: {"MD5"},
40: {"SHA-1", "RIPEMD-160"},
56: {"SHA-224", "SHA3-224"},
64: {"SHA-256", "SHA3-256", "BLAKE2s"},
96: {"SHA-384", "SHA3-384"},
128: {"SHA-512", "SHA3-512", "BLAKE2b"},
}
func identifyHash(hex string) []string {
if !hexPattern.MatchString(hex) {
return []string{"Not a hex-encoded hash"}
}
if algos, ok := hashLengths[len(hex)]; ok {
return algos
}
return []string{fmt.Sprintf("Unknown (%d hex chars)", len(hex))}
}
func main() {
fmt.Println(identifyHash("d41d8cd98f00b204e9800998ecf8427e"))
// → [MD5]
}#!/bin/bash
# Identify a hash from the command line by character count
hash="$1"
if [[ ! "$hash" =~ ^[0-9a-fA-F]+$ ]]; then
echo "Not a hex-encoded hash"
exit 1
fi
len=${#hash}
case $len in
32) echo "MD5 (128-bit)" ;;
40) echo "SHA-1 or RIPEMD-160 (160-bit)" ;;
56) echo "SHA-224 or SHA3-224 (224-bit)" ;;
64) echo "SHA-256 or SHA3-256 (256-bit)" ;;
96) echo "SHA-384 or SHA3-384 (384-bit)" ;;
128) echo "SHA-512 or SHA3-512 (512-bit)" ;;
*) echo "Unknown hash length: $len chars" ;;
esac
# Usage: ./identify.sh d41d8cd98f00b204e9800998ecf8427e
# → MD5 (128-bit)