Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hash string into RGB color

Is there a best practice on how to hash an arbitrary string into a RGB color value? Or to be more general: to 3 bytes.

You're asking: When will I ever need this? It doesn't matter to me, but imagine those tube graphs on any GitHub network page. There you can see something like this:

git branches

Where every colored line means a distinct git branch. The low tech approach to color these branches would be a CLUT (color lookup table). The more sophisticated version would be:

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

Because you want a static color every time you see the branches representation. And for bonus points: How do you ensure an even color distribution of that hash function?

So the answer to my question boils down to the implementation of hashStringToColor().

like image 546
Jens Kohl Avatar asked Jun 20 '12 13:06

Jens Kohl


People also ask

What color is 255 in RGB?

White: RGB(255,255,255) Red: RGB(255,0,0) Green: RGB(0,255,0)

Why is RGB 255?

In RGB, a color is defined as a mixture of pure red, green, and blue lights of various strengths. Each of the red, green and blue light levels is encoded as a number in the range 0.. 255, with 0 meaning zero light and 255 meaning maximum light.


2 Answers

A good hash function will provide a near uniform distribution over the key space. This reduces the question to how do I convert a random 32 bit number to a 3 byte RGB space. I see nothing wrong with just taking the low 3 bytes.

int hash = string.getHashCode(); int r = (hash & 0xFF0000) >> 16; int g = (hash & 0x00FF00) >> 8; int b = hash & 0x0000FF; 
like image 75
Jeff Foster Avatar answered Sep 22 '22 14:09

Jeff Foster


For any Javascript users out there, I combined the accepted answer from @jeff-foster with the djb2 hash function from erlycoder.

The result per the question:

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: Fixed the return string to always return a #000000 format hex string based on an edit by @alexc (thanks!).

like image 33
clayzermk1 Avatar answered Sep 26 '22 14:09

clayzermk1