【PHP実践|実務向け】ユーザー名やタグに個性を!PHPで文字列から一貫性のある色を生成する方法

導入: なぜこの技術が重要なのか

Webアプリケーションを開発していると、掲示板のユーザー名やタグ、ステータスラベルなどに「個別の色」を割り当てたい場面が多々あります。毎回データベースに色情報を保存するのは管理コストがかかりますし、ランダムに色を生成するとリロードのたびに色が変わってしまい、ユーザー体験を損ねます。
本稿では、特定の文字列に対して「常に同じ色」を割り当てる、ハッシュ値を利用した実装手法を解説します。

基礎知識: ハッシュ関数と剰余演算

今回の実装では、主に以下の2つの技術を利用します。
ハッシュ関数(md5):任意の長さの入力データから、固定長の値を生成する関数です。同じ入力に対しては必ず同じハッシュ値が生成されるという性質があります。
剰余演算(%):割り算をした時の余りを求める計算です。これにより、膨大なハッシュ値の中から「用意した色の配列のインデックス範囲内」へ数値を強制的に収めることができます。

実装/解決策

手順は非常にシンプルです。
1. カラーパレットとなる配列を定義する。
2. 対象の文字列をmd5でハッシュ化し、先頭の数文字を10進数に変換する。
3. 変換した数値を色の配列数で割り、その余りをインデックスとして色を取得する。
この方法により、文字列が同じであれば常に同じ色が選ばれる「決定論的な色割り当て」が実現可能です。

サンプルプログラム

以下のコードは、実務でもそのまま利用可能な汎用関数です。

  • 文字列に基づいて一貫した色を取得する関数
  • @param string $str 対象の文字列(ユーザー名やIDなど)
  • @param array $colors カラーコードの配列
  • @return string 選択されたカラーコード
  • /
    function stringToColor($str, array $colors) {
    // 文字列をMD5でハッシュ化し、先頭15桁を16進数から10進数へ変換
    // 15桁程度であればPHPの整数型で扱える範囲に収まりやすい
    $hash = substr(md5($str), 0, 15);
    $index = hexdec($hash) % count($colors);

    return $colors[$index];
    }

    // 利用可能なカラーパレットの定義
    $themeColors = [‘#e63946’, ‘#f1faee’, ‘#a8dadc’, ‘#457b9d’, ‘#1d3557’];

    $username = “Developer_A”;
    $color = stringToColor($username, $themeColors);
    ?>


    応用・注意点

    実務で運用する際は、以下の点に注意してください。

    色のコントラスト比を意識する
    背景色との組み合わせによっては視認性が著しく低下します。参考本文にもある通り、背景の輝度(YUV計算など)を算出し、文字色が白か黒かを自動判定するロジックを組み合わせると、よりアクセシビリティの高いUIになります。

    パレットの拡張
    色の選択肢が少なすぎると、異なるユーザー名でも同じ色が頻出します。色の数はユーザーの数や用途に応じて適宜調整してください。もしより多くのバリエーションが必要な場合は、固定の配列から選ぶのではなく、HSL色空間(色相、彩度、明度)の数値をハッシュから計算して動的に生成する手法も有効です。

    セキュリティ上の注意
    MD5は暗号学的な強度は弱いため、パスワードのハッシュ化などには決して使用しないでください。今回の用途のように「見た目の識別」といった非セキュリティ用途であれば問題ありません。

    タイトルとURLをコピーしました