简体   繁体   English

将随机字符串转换为十六进制颜色

[英]Converting a random string into a hex colour

I have a table of action logs in my application. 我的应用程序中有一个操作日志表。 I want to assign rows a random colour based on the sessionID of that entry to help see patterns/grouped actions. 我想根据该条目的sessionID为行分配一个随机颜色,以帮助查看模式/分组操作。

I have this so far: 到目前为止我有这个:

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

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

However I need to replace Math.random() with my string-integer, are there any techniques for converting a string to a random number that remains consistent with the random string? 但是我需要用我的字符串整数替换Math.random(),是否有任何技术可以将字符串转换为与随机字符串保持一致的随机数?

As requested , posting this as an awswer 根据要求 ,将其作为awswer发布

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

So, what's going on? 发生什么了?

  1. Things start on line 3 where 'mj3bPTCbIAVoNr93me1I' gets converted to an Integer , say x , by interpreting it as a base-36 number. 事情从第3行开始,其中'mj3bPTCbIAVoNr93me1I'被转换为整数 ,比如x ,将其解释为基数为36的数字。
  2. Next, x is put into it's exponential form as a String on line 4 . 接下来, x作为第4行的String以指数形式放入其中。 This is because with that many characters, x can be huge , this example is around 8e30 , so convert it to a form that will be pretty standard. 这是因为有很多字符, x可能很大 ,这个例子大约是8e30 ,所以将它转换为非常标准的形式。
  3. After this, line 5 trims off the beginning and end so you'll be left with just digits, eg '8.123e+30'.slice(2, -5) becomes '12' . 在此之后,第5行将在开始和结束时进行修剪,因此您将只留下数字,例如'8.123e+30'.slice(2, -5)变为'12'
  4. Now we go back to line 2 , where this gets converted back into an Integer again, this time in base 10. 现在我们回到第2行,再次将其转换回整数 ,这次是在基数10。
  5. Then, line 6 truncates this number down to the range 0..16777215 (=== 0xFFFFFF) using a fast bitwise AND . 然后,第6行使用快速按位AND将此数字截断到0..16777215 (=== 0xFFFFFF)范围。 This will also convert NaN to 0 . 这也将NaN转换为0
  6. Finally, line 7 converts this back into the upper case hex format we are used to seeing colours in, by writing the number in base 16 and changing the case. 最后,第7行将其转换回大写十六进制格式,我们习惯于通过在基数16写入数字并更改大小写来查看颜色。

If you want to use this, you may also want to ensure that the final number is 6 digits and stick a # on the front, which can be done via 如果你想使用它,你可能还想确保最终的数字是6位数并在正面粘贴一个# ,这可以通过

'#' + ('000000' + stringHexNumber).slice(-6); // "#32EF01"
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));
}

Sweet question. 甜蜜的问题。 What I did is create a global variable so you can consistently get the same color for a given input string. 我所做的是创建一个全局变量,以便您可以始终为给定的输入字符串获取相同的颜色。 Once you have called stringToColorCode, it will only generate a random color for that string ONCE. 一旦调用了stringToColorCode,它就只会为该字符串ONCE生成一个随机颜色。 You can rely on this to be consistent, so that if you call the function back to back with the same string, it will return the same random color. 你可以依赖它来保持一致,这样如果你用相同的字符串背靠背调用函数,它将返回相同的随机颜色。 Only flaw I see is that it's possibly (but unlikely) that two different strings could be mapped to the same color, but that could be worked around if necessary. 我看到的唯一缺陷是,可能(但不太可能)两个不同的字符串可以映射到相同的颜色,但如果需要可以解决。

Edit: When first answering, I didn't realize @Nirk had practically the same answer. 编辑:第一次回答时,我没有意识到@Nirk几乎有相同的答案。 To make this one a little more unique, use this which will give you consistent colors across page reloads. 为了使这个更独特一点,使用它可以在页面重新加载时为您提供一致的颜色。

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;
}

I resolved this on backing bean. 我在支持bean上解决了这个问题。 This works for me in Java: 这适用于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();
    }
}

I made the generated color a little darker for a white background... 我为白色背景生成的颜色稍暗一些......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM