将string散列成RGB颜色

有没有最佳做法如何散列任意string到RGB颜色值? 或者更一般地说:3个字节。

你问:我什么时候需要这个? 对我来说没有关系,但想象一下任何GitHub 网页上的pipe图。 在那里你可以看到这样的东西:

混帐分支

每条彩色线代表一个独特的git分支。 对这些分支着色的低科技方法将是一个CLUT(颜色查找表)。 更复杂的版本将是:

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

因为每次看到分支表示时都需要一个静态颜色。 而对于奖励点:如何确保散列函数的颜色分布均匀?

所以我的问题的答案归结为hashStringToColor()的实现。

一个好的散列函数将在密钥空间上提供一个接近均匀的分布。 这减less了如何将随机的32位数字转换为3字节的RGB空间的问题。 我只看到低3字节,没有看到任何错误。

 int hash = string.getHashCode(); int r = (hash & 0xFF0000) >> 16; int g = (hash & 0x00FF00) >> 8; int b = hash & 0x0000FF; 

对于任何Javascript用户,我将@ jeff-foster接受的答案与djb2哈希函数结合在一起 。

每个问题的结果:

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

更新 :修正了返回string总是返回一个#000000格式的hexstring基于@alexc编辑(谢谢!)。

我尝试了其他人提供的所有解决scheme,但发现类似的string(string1 vs string2)产生的颜色与我的喜好太相似。 所以,我build立了自己的影响他人的input和想法。

这个将计算string的MD5校验和,并取前6个hex数字来定义RGB 24位代码。

MD5function是一个开源的JQuery插件.JSfunction如下:

 function getRGB(str){ var hash = $.md5(str); var rgb = '#' + hash.substring(0,2) + hash.substring(2,4) + hash.substring(4,6); return rgb; } 

这个工作示例的链接是在jsFiddle上 。 只要在input字段中input一个string,然后按下回车键,并反复执行以比较您的发现。

我只是build立一个名为color-hash的JavaScript库,它可以基于给定的string(使用HSL颜色空间和BKDRHash)生成颜色。

回购: https : //github.com/zenozeng/color-hash
演示: https : //zenozeng.github.io/color-hash/demo/

作为一个例子, 这是Java如何计算一个string (1494行及以下) 的哈希码 。 它返回一个int 。 然后,你可以用16,777,216(2 ^ 24 = 3个字节)来计算这个int的模数来得到一个“RGB兼容”的数字。

这是一个确定性的计算,所以相同的单词总是会有相同的颜色。 哈希碰撞的可能性(2个具有相同颜色的string)很小。 不知道颜色分布,但可能相当随机。