Преобразование случайной строки в шестнадцатеричный цвет

В моем приложении есть таблица журналов действий. Я хочу назначить строки случайным цветом на основе идентификатора sessionID этой записи, чтобы помочь увидеть шаблоны/сгруппированные действия.

У меня это до сих пор:

console.log(stringToColorCode('mj3bPTCbIAVoNr93me1I'));

function stringToColorCode(str) {
    return '#'+ ('000000' + (Math.random()*0xFFFFFF<<0).toString(16)).slice(-6);
}

Однако мне нужно заменить Math.random() моим строковым целым, есть ли какие-либо методы для преобразования строки в случайное число, которое остается согласованным со случайной строкой?

Ответы

Ответ 1

var color_codes = {};
function stringToColorCode(str) {
    return (str in color_codes) ? color_codes[str] : (color_codes[str] = '#'+ ('000000' + (Math.random()*0xFFFFFF<<0).toString(16)).slice(-6));
}

Ответ 2

В соответствии с запросом, разместив это как ответ

var stringHexNumber = (                       // 1
    parseInt(                                 // 2
        parseInt('mj3bPTCbIAVoNr93me1I', 36)  // 3
            .toExponential()                  // 4
            .slice(2,-5)                      // 5
    , 10) & 0xFFFFFF                          // 6
).toString(16).toUpperCase(); // "32EF01"     // 7

Итак, что происходит?

  • Вещи начинаются в строке 3, где 'mj3bPTCbIAVoNr93me1I' преобразуется в целое число, скажем x, интерпретируя его как номер базы 36.
  • Затем x помещается в него экспоненциальная форма как строка в строке 4. Это связано с тем, что с таким количеством символов x может быть огромным, этот пример находится вокруг 8e30, поэтому преобразуйте его в форму, которая будет довольно стандартной.
  • После этого строка 5 обрезает начало и конец, поэтому вы останетесь с просто цифрами, например. '8.123e+30'.slice(2, -5) становится '12'.
  • Теперь мы возвращаемся к строке 2, где это снова возвращается в Integer, на этот раз в базе 10.
  • Затем строка 6 обрезает это число до диапазона 0..16777215 (=== 0xFFFFFF) с использованием быстрого побитового И. Это также преобразует NaN в 0.
  • Наконец, строка 7 преобразует это обратно в шестнадцатеричный формат в верхнем регистре, который мы используем для просмотра цветов, путем записи числа в базе 16 и изменения случая.

Если вы хотите использовать это, вы также можете убедиться, что конечное число 6 цифр и придерживаться # на передней панели, что можно сделать с помощью

'#' + ('000000' + stringHexNumber).slice(-6); // "#32EF01"

Ответ 3

Сладкий вопрос. То, что я сделал, это создать глобальную переменную, чтобы вы могли последовательно получать один и тот же цвет для заданной входной строки. Как только вы вызываете stringToColorCode, он будет генерировать только случайный цвет для этой строки ONCE. Вы можете полагаться на это, чтобы быть последовательным, так что, если вы вызовете функцию назад к одной и той же строке, она вернет тот же случайный цвет. Единственный недостаток, который я вижу, состоит в том, что возможно (но маловероятно), что две разные строки могут быть сопоставлены одному и тому же цвету, но при необходимости можно было бы работать вокруг.

Изменить: При первом ответе я не понял, что @Nirk имел практически тот же ответ. Чтобы сделать это немного более уникальным, используйте это, которое даст вам согласованные цвета для перезагрузки страниц.

console.log(stringToColorCode('mj3bPTCbIAVoNr93me1I'));

function stringToColorCode(str) {
    var sessionStoreKey = "myStringColors" + str;
    if (!sessionStorage[sessionStoreKey ]) {
        sessionStorage[sessionStoreKey] = Math.random()*0xFFFFFF<<0;       
    }

    var randomColor = sessionStorage[sessionStoreKey];

    return '#'+ randomColor;
}

Ответ 4

Я решил это при поддержке bean. Это работает для меня на Java:

private void createDefaultColorFromName(final String name) {
    String md5 = "#" + md5(name).substring(0, 6);
    defaultColor = Color.decode(md5);
    int darkness = ((defaultColor.getRed() * 299) + (defaultColor.getGreen() * 587) + (defaultColor.getBlue() * 114)) / 1000;
    if (darkness > 125) {
        defaultColor = defaultColor.darker();
    }
}

Я сделал сгенерированный цвет немного темнее для белого фона...