Подтвердить что ты не робот

Хэш-строка в цвет RGB

Существует ли наилучшая практика того, как хэш произвольной строки в значение цвета RGB? Или быть более общим: до 3 байтов.

Вы спрашиваете: когда мне это понадобится? Для меня это не имеет значения, но представьте эти диаграммы на любой странице GitHub . Там вы можете увидеть что-то вроде этого:

git branches

Где каждая цветная линия означает отдельную ветвь git. Низкотехнологичный подход для окраски этих ветвей был бы CLUT (таблица цветового поиска). Более сложная версия:

$branchColor = hashStringToColor(concat($username,$branchname));

Потому что вы хотите статический цвет каждый раз, когда видите представление ветвей. И для бонусных очков: как вы обеспечиваете равномерное распределение цветов этой хэш-функции?

Таким образом, ответ на мой вопрос сводится к реализации hashStringToColor().

4b9b3361

Ответ 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 строки одного цвета) мала. Не уверен в распределении цветов, но, вероятно, довольно случайный.