任意の文字列をRGBカラー値にハッシュするベストプラクティスはありますか?または、より一般的には、3バイトに。
あなたが求めているのは、いつこれが必要になるかです。それは私には関係ありませんが、GitHub ネットワークページ でこれらのチューブグラフを想像してください。そこで、次のようなものが表示されます。
すべての色付きの線は、別個のgitブランチを意味します。これらのブランチに色を付けるためのローテクアプローチは、CLUT(カラールックアップテーブル)です。より洗練されたバージョンは次のとおりです。
_$branchColor = hashStringToColor(concat($username,$branchname));
_
ブランチの表示を見るたびに静的な色が欲しいからです。そしてボーナスポイントについて:どのようにしてそのハッシュ関数の均一な色分布を保証しますか?
だから私の質問への答えはhashStringToColor()
の実装に要約されます。
優れたハッシュ関数は、キースペース全体でほぼ均一な分布を提供します。これにより、ランダムな32ビットの数値を3バイトのRGBスペースに変換する方法に関する質問が減ります。下位3バイトを取得するだけで問題はありません。
int hash = string.getHashCode();
int r = (hash & 0xFF0000) >> 16;
int g = (hash & 0x00FF00) >> 8;
int b = hash & 0x0000FF;
そこにいるすべてのJavascriptユーザーに対して、@ jeff-fosterから受け入れられた回答とdjb2
erlycoder からのハッシュ関数。
質問ごとの結果:
function djb2(str){
var hash = 5381;
for (var i = 0; i < str.length; i++) {
hash = ((hash << 5) + hash) + str.charCodeAt(i); /* hash * 33 + c */
}
return hash;
}
function hashStringToColor(str) {
var hash = djb2(str);
var r = (hash & 0xFF0000) >> 16;
var g = (hash & 0x00FF00) >> 8;
var b = hash & 0x0000FF;
return "#" + ("0" + r.toString(16)).substr(-2) + ("0" + g.toString(16)).substr(-2) + ("0" + b.toString(16)).substr(-2);
}
[〜#〜] update [〜#〜]:@alexcによる編集に基づいて常に#000000形式の16進文字列を返すように戻り文字列を修正しました(ありがとう!).
他のソリューションをすべて試しましたが、類似の文字列(string1とstring2)が、好みに合わせて色が似すぎていることを発見しました。そのため、他者の意見やアイデアに影響を受けて自分で構築しました。
これは、文字列のMD5チェックサムを計算し、最初の6桁の16進数を取り、RGB 24ビットコードを定義します。
MD5機能はオープンソースのJQueryプラグインです。JS関数は次のように機能します。
function getRGB(str){
var hash = $.md5(str);
var rgb = '#' + hash.substring(0,2) + hash.substring(2,4) + hash.substring(4,6);
return rgb;
}
この実用例へのリンクは jsFiddle にあります。入力フィールドに文字列を入力してEnterキーを押すだけで、何度も繰り返し入力して結果を比較できます。
(HSL色空間とBKDRHashを使用して)指定された文字列に基づいて色を生成できるcolor-hashという名前のJavaScriptライブラリをビルドするだけです。
リポジトリ: https://github.com/zenozeng/color-hash
デモ: https://zenozeng.github.io/color-hash/demo/
例として、- これはJava文字列のハッシュコードを計算する方法 (1494行目以降)です。これはint
を返します。そのint
のモジュロを16,777,216(2 ^ 24 = 3バイト)で計算して、「RGB互換」の数値を取得します。
これは確定的な計算であるため、同じ単語は常に同じ色になります。ハッシュの衝突(同じ色の2つの文字列)の可能性は小さいです。色の分布についてはわかりませんが、おそらくかなりランダムです。