Хэш-строка в цвет RGB
Существует ли наилучшая практика того, как хэш произвольной строки в значение цвета RGB? Или быть более общим: до 3 байтов.
Вы спрашиваете: когда мне это понадобится? Для меня это не имеет значения, но представьте эти диаграммы на любой странице GitHub . Там вы можете увидеть что-то вроде этого:
![git branches]()
Где каждая цветная линия означает отдельную ветвь git. Низкотехнологичный подход для окраски этих ветвей был бы CLUT (таблица цветового поиска). Более сложная версия:
$branchColor = hashStringToColor(concat($username,$branchname));
Потому что вы хотите статический цвет каждый раз, когда видите представление ветвей. И для бонусных очков: как вы обеспечиваете равномерное распределение цветов этой хэш-функции?
Таким образом, ответ на мой вопрос сводится к реализации hashStringToColor()
.
Ответы
Ответ 1
Хорошая хэш-функция обеспечит почти равномерное распределение по ключевому пространству. Это уменьшает вопрос о том, как преобразовать случайное 32-разрядное число в 3-байтное пространство RGB. Я не вижу ничего плохого в том, что просто беру минимум 3 байта.
int hash = string.getHashCode();
int r = (hash & 0xFF0000) >> 16;
int g = (hash & 0x00FF00) >> 8;
int b = hash & 0x0000FF;
Ответ 2
Для всех пользователей 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: исправлена возвращаемая строка, которая всегда возвращает шестнадцатеричную строку формата # 000000 на основе редактирования @alexc (спасибо!).
Ответ 3
Я попробовал все решения, предоставленные другими, но обнаружил, что похожие строки (string1 vs string2) производят цвета, которые слишком похожи на мой вкус. Поэтому я построил свой собственный под влиянием вклада и идей других.
Он вычислит контрольную сумму MD5 строки и возьмет первые 6 шестнадцатеричных цифр, чтобы определить 24-битный код RGB.
Функциональность MD5 - это плагин JQuery с открытым исходным кодом.
Функция JS работает следующим образом:
function getRGB(str) {
return '#' + $.md5(str).substring(0, 6);
}
Ссылка на этот рабочий пример находится на jsFiddle. Просто введите строку в поле ввода и нажмите клавишу ввода, и делайте это снова и снова, чтобы сравнить свои результаты.
Ответ 4
Я просто создаю библиотеку JavaScript с именем color-hash, которая может генерировать цвет на основе заданной строки (используя цветовое пространство HSL и BKDRHash).
Репо: https://github.com/zenozeng/color-hash
Демо-версия: https://zenozeng.github.io/color-hash/demo/
Ответ 5
В качестве примера это то, как Java вычисляет хэш-код строки (строка 1494 и следующая). Он возвращает int
. Затем вы можете вычислить по модулю этого int
с 16 777 216 (2 ^ 24 = 3 байта), чтобы получить "совместимый с RGB" номер.
Это детерминированный расчет, поэтому одно и то же слово всегда будет иметь один и тот же цвет. Вероятность столкновения хешей (2 строки одного цвета) мала. Не уверен в распределении цветов, но, вероятно, довольно случайный.