# 機能設計書 63-ハッシュ計算

## 概要

本ドキュメントは、Nushellにおけるハッシュ計算機能（hash コマンド群）の設計を記述する。MD5およびSHA-256アルゴリズムによるハッシュ値計算を提供し、データの整合性確認やフィンガープリント生成に使用できる。

### 本機能の処理概要

ハッシュ計算機能は、文字列やバイナリデータに対してMD5またはSHA-256アルゴリズムでハッシュ値を計算する。出力形式として16進数文字列またはバイナリを選択できる。

**業務上の目的・背景**：ファイルの整合性確認、データの重複検出、パスワードハッシュ（非推奨だが）、キャッシュキーの生成など、ハッシュ値は様々な用途で使用される。ファイルダウンロード後のチェックサム検証や、データパイプラインでのデータ変更検出に活用できる。

**機能の利用シーン**：
- ダウンロードしたファイルのチェックサム検証
- ファイルやデータの重複検出
- キャッシュキーの生成
- データ整合性の確認
- ファイルの一意識別子としてのフィンガープリント生成

**主要な処理内容**：
1. `hash md5` - MD5ハッシュ値を計算（128ビット）
2. `hash sha256` - SHA-256ハッシュ値を計算（256ビット）

**関連システム・外部連携**：外部システムとの直接連携はない。Rustの`md5`および`sha2`クレートを使用する。

**権限による制御**：特別な権限制御はなく、すべてのユーザーが実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 結果表示画面 | コマンド実行結果としてのハッシュ値表示 |

## 機能種別

計算処理

## 入力仕様

### 入力パラメータ

#### hash md5 / hash sha256

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --binary, -b | Switch | No | バイナリ形式で出力 | - |
| rest | CellPath | No | 対象セルパス（レコード/テーブル用） | 有効なセルパス |

### 入力データソース

- **パイプライン入力**: String, Binary, ByteStream, Table, Record
- **文字列**: UTF-8エンコードでバイト列に変換
- **バイナリ**: そのままハッシュ計算
- **ByteStream**: ストリーミング処理で逐次ハッシュ計算
- **テーブル/レコード**: 指定したセルパスの値をハッシュ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ハッシュ値（デフォルト） | String | 16進数小文字の文字列 |
| ハッシュ値（--binary） | Binary | バイナリ形式のハッシュ値 |

### 出力先

パイプラインへの出力（PipelineData）。

## 処理フロー

### 処理シーケンス

```
1. コマンドの引数解析
   └─ --binary フラグ、セルパスを取得

2. 入力データの判定
   └─ ByteStream の場合はストリーミング処理
   └─ その他の場合は operate() で処理

3. ハッシュ計算
   └─ digest::Digest トレイトを使用
   └─ MD5 または SHA-256 アルゴリズムで計算

4. 結果のフォーマット
   └─ --binary: バイナリ値として返却
   └─ デフォルト: 16進数文字列として返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{入力の種類}
    B -->|ByteStream| C[ストリーミング処理]
    B -->|String/Binary| D[バッチ処理]
    B -->|Table/Record| E[セルパス処理]
    C --> F[hasher.write_to]
    D --> G[D::digest bytes]
    E --> H[operate で各セル処理]
    F --> I[hasher.finalize]
    G --> I
    H --> I
    I --> J{--binary?}
    J -->|Yes| K[Value::binary]
    J -->|No| L[format! hex -> Value::string]
    K --> M[PipelineData返却]
    L --> M
    M --> N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | デフォルト出力形式 | 16進数小文字文字列 | --binary 省略時 |
| BR-002 | MD5長さ | 出力は32文字（128ビット/4） | hash md5 |
| BR-003 | SHA256長さ | 出力は64文字（256ビット/4） | hash sha256 |
| BR-004 | 入力型制限 | String または Binary のみ許可 | 常時 |
| BR-005 | ストリーミング対応 | ByteStreamは逐次処理でメモリ効率的 | ByteStream入力時 |

### 計算ロジック

- **MD5**: RFC 1321準拠の128ビットハッシュ
- **SHA-256**: FIPS 180-4準拠の256ビットハッシュ
- ハッシュ計算は `digest::Digest` トレイトを実装したジェネリック実装

## データベース操作仕様

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| OnlySupportsThisInputType | 型エラー | String/Binary以外の入力 | String または Binary を入力 |
| IoError | IO エラー | ByteStream読み取りエラー | 入力ストリームを確認 |

### リトライ仕様

リトライは不要。ハッシュ計算は決定論的であり、同じ入力には同じ結果が返る。

## トランザクション仕様

本機能はトランザクション管理を行わない。

## パフォーマンス要件

- ハッシュ計算は高速（数MB/秒オーダー）
- ByteStreamのストリーミング処理により大容量ファイルも効率的に処理可能
- MD5はSHA-256より高速だが、セキュリティ用途には推奨されない

## セキュリティ考慮事項

- MD5は衝突攻撃に脆弱であり、セキュリティ用途には使用しないこと
- パスワードハッシュにはMD5/SHA-256を直接使用せず、専用のパスワードハッシュ関数（bcrypt, argon2等）を使用すること
- ファイル整合性確認やデータフィンガープリントにはSHA-256を推奨

## 備考

- 将来的に他のハッシュアルゴリズム（SHA-512等）の追加が検討される可能性あり

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: モジュール構成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mod.rs | `crates/nu-command/src/hash/mod.rs` | 公開されるコマンド一覧 |

**読解のコツ**: Hash, HashMd5, HashSha256 の3つがエクスポートされている。

#### Step 2: ジェネリック実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | generic_digest.rs | `crates/nu-command/src/hash/generic_digest.rs` | コア実装 |

**主要処理フロー**:
- **5-8行目**: `HashDigest` トレイト定義（name と examples を要求）
- **10-25行目**: `GenericDigest<D>` 構造体（ジェネリックなコマンド実装）
- **38-103行目**: `Command` トレイト実装
- **47-67行目**: シグネチャ定義（--binary フラグ、rest パラメータ）
- **77-102行目**: `run()` メソッド
- **90-97行目**: ByteStream の場合のストリーミング処理
- **105-138行目**: `action()` 関数（個々の値に対するハッシュ計算）

#### Step 3: 具体的なアルゴリズム実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | md5.rs | `crates/nu-command/src/hash/md5.rs` | MD5固有の設定 |
| 3-2 | sha256.rs | `crates/nu-command/src/hash/sha256.rs` | SHA-256固有の設定 |

**主要処理フロー（md5.rs）**:
- **5行目**: `pub type HashMd5 = GenericDigest<Md5>;` - 型エイリアス
- **7-40行目**: `HashDigest for Md5` - name() と examples() の実装

#### Step 4: 親コマンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | hash_.rs | `crates/nu-command/src/hash/hash_.rs` | hash コマンド本体 |

**主要処理フロー**:
- **31-33行目**: ヘルプ表示のみ（サブコマンドが必要）

### プログラム呼び出し階層図

```
hash (hash_.rs)
    │
    ├─ hash md5 (md5.rs + generic_digest.rs)
    │      │
    │      └─ GenericDigest<Md5>::run()
    │             │
    │             ├─ ByteStream入力
    │             │      └─ stream.write_to(&mut hasher)
    │             │      └─ hasher.finalize()
    │             │
    │             └─ その他入力
    │                    └─ operate(action::<Md5>, ...)
    │                           └─ Md5::digest(bytes)
    │
    └─ hash sha256 (sha256.rs + generic_digest.rs)
           │
           └─ GenericDigest<Sha256>::run()
                  └─ (同上の構造)
```

### データフロー図

```
[入力]                     [処理]                              [出力]

String ────────────▶ val.as_bytes() ────────────▶ D::digest()
                                                       │
Binary ────────────▶ val.as_slice() ────────────▶ D::digest()
                                                       │
ByteStream ────────▶ stream.write_to(hasher) ──▶ finalize()
                                                       │
                                                       ▼
                                              ┌─────────────────┐
                                              │  digest 結果    │
                                              └─────────────────┘
                                                       │
                                    ┌──────────────────┴──────────────────┐
                                    │                                     │
                              --binary                              デフォルト
                                    │                                     │
                                    ▼                                     ▼
                            Value::binary                      format!("{:x}")
                                    │                                     │
                                    └──────────────┬──────────────────────┘
                                                   │
                                                   ▼
                                           PipelineData返却
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| mod.rs | `crates/nu-command/src/hash/mod.rs` | ソース | モジュール定義 |
| hash_.rs | `crates/nu-command/src/hash/hash_.rs` | ソース | 親コマンド |
| generic_digest.rs | `crates/nu-command/src/hash/generic_digest.rs` | ソース | ジェネリックハッシュ実装 |
| md5.rs | `crates/nu-command/src/hash/md5.rs` | ソース | MD5固有設定 |
| sha256.rs | `crates/nu-command/src/hash/sha256.rs` | ソース | SHA-256固有設定 |
