Max Williams Max Williams - 1 month ago 12
Ruby Question

Generate an rgb color from a user's name (in a repeatable way)

I'd like to set a consistent color for a user's default avatar background, according to the following rules:


  • rgb value, where each number can not be higher than 200 (ie between 0 and 200)

  • use the full name, eg "John Smith" and "John Smithy" would give different colors.

  • A small change to the name should create a totally different color.



I'm thinking of something along these lines:


  • hash the name into something which consists of three equal parts

  • take each of the three parts and normalise it to a float between 0 and 1

  • multiply these by 200 to get the r, g or b value.



But I can't quite figure out how to go about it. Any suggestions? If I could do it without getting any extra gems that would be ideal. I already use MD5 for some hashing stuff.

NOTE: this isn't a security issue, it's just a bit of fun, so if two different names end up generating the same color once in a while it doesn't matter too much, but generally it would be nice to have the color values as varied as possible.

Answer

You could build an MD5-hash of the user's name via:

require 'digest'

name = 'foo'
digest = Digest::MD5.digest(name)
#=> "\xAC\xBD\x18\xDBL\xC2\xF8\\\xED\xEFeO\xCC\xC4\xA4\xD8"

Extract the first three 16-bit integers:

values = digest.unpack('SSS')
#=> [48556, 56088, 49740]

And map these 0..65535 values to 0..200:

values.map { |i| i * 201 / 0x10000 }
#=> [148, 172, 152]