乱数は「運」ではなく「設計」である:PHPからHack `HSL\Random` への完全移行ガイド
こんにちは。Hackの深淵へようこそ。
日々、HHVMのJITコンパイラが吐き出す機械語と型チェッカーの厳格な警告に向き合っていると、「予測可能性」こそがシステムの死を招く最大の脆弱性であると痛感します。
今回は、PHP時代からの悪癖である「不完全な乱数」を捨て、Hackの `HSL (Hack Standard Library)` が提供する堅牢な乱数生成の世界へ飛び込みましょう。
—
1. なぜ PHP の `rand()` は「禁忌」なのか
PHPの `rand()` や `mt_rand()` は、歴史的な遺産です。これらは「メルセンヌ・ツイスタ」などのアルゴリズムに基づいていますが、暗号学的な安全性(Cryptographically Secure)は保証されていません。
- 問題点: シード(乱数の種)さえ推測できれば、次に出現する数値を完全に予測可能です。トークン生成やパスワードリセットの照合にこれらを使うのは、鍵のかかっていない玄関に貴重品を置くようなものです。
Hackに移行したなら、迷わず `HH\Lib\Random` を使いましょう。これはOSの暗号学的乱数生成器(Linuxなら `/dev/urandom`)を直接叩くため、予測不能です。
—
2. HSL Random の基本:こう書けば安全だ
HSLの乱数は非常にシンプルです。シード管理?不要です。私たちは「状態」を持たない純粋なコードを好むのですから。
use namespace HH\Lib\Random;
<<__EntryPoint>>
function main(): void {
// 0 から 99 までの安全な整数を生成
$lucky_number = Random\int(0, 99);
// 暗号学的に安全なランダムな文字列(トークンなど)の生成
// 32バイトのバイナリを生成し、それを16進数に変換する
$token = \bin2hex(Random\bytes(32));
\printf(“Lucky: %d\nToken: %s\n”, $lucky_number, $token);
}
ここがポイント!
- シード不要: `srand()` を呼び出す必要はありません。それは過去の遺物です。
- 型安全: `Random\int` は引数として `int` を要求し、戻り値も `int` です。型チェッカーが、範囲外の不正な値を事前に防いでくれます。
—
3. よくある罠:配列のシャッフル
PHPでは `shuffle($arr)` を使いがちですが、これは「副作用」の塊です。元の配列を直接書き換えるため、バグの温床になります。
Hack(HSL)では、イミュータブル(不変)な考え方で処理します。
use namespace HH\Lib\Vec;
use namespace HH\Lib\Random;
function get_randomized_list(vec
// Random\shuffle は元の配列を破壊せず、新しい配列を返す
return Random\shuffle($items);
}
【初心者が陥りやすいエラー】
「`shuffle($items)` と書いたのに、戻り値が `void` になってしまう!」と悩む人がいます。PHPの `shuffle` は戻り値が `bool` で、引数を直接変更しますが、HSLの `Random\shuffle` は新しい配列を生成して返すという、関数型言語的なアプローチを取っています。この「戻り値を受け取る」という意識改革こそが、Hackをマスターする第一歩です。
—
4. 比較図解:PHP vs Hack
| 特徴 | PHP (`rand`) | Hack (`HSL\Random`) |
| :— | :— | :— |
| 安全性 | 低(推測可能) | 高(暗号論的) |
| シード管理 | 必須(プログラマ責任) | 不要(自動処理) |
| 設計思想 | 破壊的(副作用あり) | 関数的(不変性) |
| 型安全性 | なし | 厳格(型チェックによる保護) |
—
5. 先輩からのアドバイス:安全は「型」から始まる
Hackの静的型システムは、あなたのコードの守護神です。
`Random\int` を使うとき、もしあなたが誤って浮動小数点数を渡そうとしたら、実行する前に型チェッカーが赤色の文字で「それは認めない」と教えてくれます。
乱数のような「見えないデータ」を扱うときこそ、この厳格な境界線が活きてきます。予測不可能な乱数を、予測可能な型でラップする。これこそが、堅牢なシステムを構築するプロフェッショナルの流儀です。
—
まとめ:今日からできること
1. 既存コードの `rand()`, `mt_rand()` をすべて検索し、`Random\int()` に置き換える準備をする。
2. `shuffle()` を使っている箇所を `Random\shuffle()` に変え、戻り値を変数に代入する形に書き換える。
3. もし「予測可能性」が必要なテストケースがあるなら、それは乱数生成器ではなく、モック(Mock)で値を固定する設計に切り替える。
ここをクリアすれば、あなたはもうただのPHP書きではありません。型という名の武器を携えた、Hackエンジニアの仲間入りです。
さあ、次はどんな壁を乗り越えに行きましょうか?質問があればいつでもどうぞ。あなたのコードが、より安全で洗練されたものになることを願っています。