如何将字符串转换为HTML颜色代码哈希?

25

我希望将字符串表示为任意的html颜色。

例如:

"blah blah" = #FFCC00
"foo foo 2" = #565656

实际的颜色代码并不重要,只要它是有效的十六进制HTML颜色代码,并且整个光谱被相对平均地表示即可。

我想第一步应该是对字符串进行MD5,然后以某种方式将其转换为十六进制颜色代码?

更新:使用示例是为了在服务器上生成文件请求的视觉报告。 颜色不必看起来漂亮,更多是为了人类大脑能够更容易地检测到数据中的模式等。


你想将一个字符串映射到一个6位十六进制代码吗? - codaddict
你能举个例子说明如何使用这些字符串吗?为什么不将颜色代码放在PHP变量中呢? - Mischa
1
跟随codaddict的思路:将其哈希化并取前6个字节? - russau
使用示例是生成服务器上文件请求的可视化报告。颜色不必看起来漂亮,更多的是为了人类大脑更容易地检测数据中的模式等。 - user217562
所以根据文件请求的数量,您想在php中为文件名赋予不同的颜色? - Mischa
显示剩余2条评论
4个回答

55

谢谢你的指导,这个方法看起来做得很好:

function stringToColorCode($str) {
  $code = dechex(crc32($str));
  $code = substr($code, 0, 6);
  return $code;
}

$str = 'test123';
print '<span style="background-color:#'.stringToColorCode($str).'">'.$str.'</span>';

3
正是我在寻找的解决方案。 - Pascal Klein
2
这里提供了一个类似的概念但不同的哈希:https://dev59.com/E3DXa4cB1Zd3GeqP-ko1 对我来说,它似乎提供了更多样化的颜色组合。也许md5()与dechex(crc32())的哈希分布不同。 - kane
为什么不直接使用bin2hex()和substr()函数呢? - Aryan

27

通常情况下,仅使用随机颜色会:

  1. 看起来不好看
  2. 与背景产生冲突

我建议创建一个(较长的)颜色列表,这些颜色彼此之间和背景搭配得很好 - 然后只需对字符串进行哈希并取模(%)以获得索引表中的索引。

public function colorFromString($string)
{
  $colors = [
    '#0074D9',
    '#7FDBFF',
    '#39CCCC',
    // this list should be as long as practical to avoid duplicates
  ];

  // generate a partial hash of the string (a full hash is too long for the % operator)
  $hash = substr(sha1($string), 0, 10);

  // determine the color index
  $colorIndex = hexdec($hash) % count($colors);

  return $colors[$colorIndex];
}

1
这是最好的答案。你应该包含一个函数才能使其完整。 - Heroselohim

21
我同意sje397的观点,完全随机的颜色可能看起来很糟糕。与其列出一长串好看的颜色,我建议选择一个恒定的饱和度+亮度值,并根据内容变换色调。要从HSL颜色获取RGB颜色,可以使用类似于http://en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB中描述的内容。
这里有个例子(在http://codepad.viper-7.com中尝试它,或者在https://codepad.remoteinterview.io/ZXBMZWYJFO等可用的地方)。
<?php

function hsl2rgb($H, $S, $V) {
    $H *= 6;
    $h = intval($H);
    $H -= $h;
    $V *= 255;
    $m = $V*(1 - $S);
    $x = $V*(1 - $S*(1-$H));
    $y = $V*(1 - $S*$H);
    $a = [[$V, $x, $m], [$y, $V, $m],
          [$m, $V, $x], [$m, $y, $V],
          [$x, $m, $V], [$V, $m, $y]][$h];
    return sprintf("#%02X%02X%02X", $a[0], $a[1], $a[2]);
}

function hue($tstr) {
    return unpack('L', hash('adler32', $tstr, true))[1];
}

$phrase = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
$words = [];
foreach (explode(' ', $phrase) as $word)
    $words[hue($word)] = $word;
ksort($words);
foreach ($words as $h => $word) {
    $col = hsl2rgb($h/0xFFFFFFFF, 0.4, 1);
    printf('<span style="color:%s">%s</span> ', $col, $word);
}
?>

PHP 解析错误:由于旧的 PHP 版本,在 $a 后面出现了意外的 '['。 - hozza
这将解决解析问题:$a = [[$V,$x,$m],[$y,$V,$m],[$m,$V,$x],[$m,$y,$V],[$x,$m,$V],[$V,$m,$y]]; $a = $a [$h]; - ZPiDER
顺便提一下 - 我发现这个函数可以生成好的文本颜色:function colorFromText($text) { return hsl2rgb(hueFromText($text)/0xFFFFFFFF, 0.8, 0.6); } - ZPiDER
谢谢你提供的代码片段。不幸的是,在我的情况下,它生成的颜色非常相似。对于大约20个两位数,我得到的颜色都在绿色和黄色之间。如果我先使用sha1()哈希$tstr,我确实会得到更多的颜色,但其中一些仍然看起来像重复的。是否有更好的方法将任意文本转换为色调,或者对于我的约20个值,我要求太多了? - ᴍᴇʜᴏᴠ

13

一个简短的句子:

substr(md5($string), 0, 6);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接