Gravatars/identicons with Mathematica

21

7

The default avatar/identicon is based on an MD5 hash of your e-mail address. With some e-mail providers (e.g., GMail) the address gmailuser+foo@gmail.com is still delivered to gmailuser@gmail.com, so this trick can be used to change the hash of your e-mail and thus get a different identicon, but there is no guarantee that it looks better than the original.

How can we semi-automate the search for your preferred identicon using Mathematica?

VLC

Posted 2012-10-23T15:16:11.083

Reputation: 9 520

2Of course the guaranteed way to get a pretty gravatar is to explicitly set it to a pretty picture. :-) – celtschk – 2012-10-23T15:40:07.807

@celtschk Not everyone might want to sign up to Gravatar. – VLC – 2012-10-23T15:42:59.563

By the way, I think Leonid has one of the best generated Gravatars in the system and AFAIK it's for his real email address. – Mr.Wizard – 2012-10-23T17:33:13.310

This is exactly how I picked my autogenerated gravatar (for those that remember) before I became the hypnotoad

– rm -rf – 2012-10-23T19:03:30.603

Answers

24

With this function a random integer is inserted in the e-mail address (gmailuser@gmail.com becomes gmailuser+randominteger@gmail.com) and then the hash value is computed. The hash value is used to get the corresponding identicon from the Gravatar website. This approach can address also some privacy concerns.

generatePic[email_] := 
 Module[{emailparts, randN, input, inputhash, img},
  emailparts = StringSplit[email, "@"];
  randN = StringJoin["+", ToString[RandomInteger[99999]], "@"];
  input = emailparts[[1]] <> randN <> emailparts[[2]];
  inputhash = IntegerString[Hash[ToLowerCase[input], "MD5"], 16, 32];
  img = Import[
    "http://www.gravatar.com/avatar/" <> inputhash <> 
     "?s=128&d=identicon&r=PG"];
  {img, input}
  ]

If we want to generate some identicons based on a specific e-mail address we just do this:

Grid[Table[generatePic["gmailuser@gmail.com"], {3}]]

identicons

Once we find an identicon we like, we just need to copy/paste the corresponding e-mail address into the e-mail field of the Stack Exchange profile.

Update for Mathematica versions before 8

It seems that older Mathematica versions include the enclosing quotes "" when it generates the hash, but there seems to be a workaround.

StringHash[string_String, type_: "MD5"] := 
 Module[{stream, file, hash}, stream = OpenWrite[];
  WriteString[stream, string];
  file = Close[stream];
  hash = FileHash[file, type];
  DeleteFile[file];
  hash]

And then:

generatePic[email_] := 
 Module[{emailparts, randN, input, inputhash, img}, 
  emailparts = StringSplit[email, "@"];
  randN = StringJoin["+", ToString[RandomInteger[99999]], "@"];
  input = emailparts[[1]] <> randN <> emailparts[[2]];
  inputhash = 
   IntegerString[StringHash[ToLowerCase[input], "MD5"], 16, 32];
  img = Import[
    "http://www.gravatar.com/avatar/" <> inputhash <> 
     "?s=128&d=identicon&r=PG"];
  {img, input}]

VLC

Posted 2012-10-23T15:16:11.083

Reputation: 9 520

I wish I had thought of this. Nice work! – Mr.Wizard – 2012-10-23T15:36:53.503

I've got a problem: The avatar produced by your function doesn't match the one I get when I enter the email address in the profile here on StackExchange. – Mr.Wizard – 2012-10-23T15:49:24.580

@Mr.Wizard I've tried several gmail addresses and they always matched. I'll try to see where the problem could be. – VLC – 2012-10-23T16:00:39.190

Then either it's my problem or v7 hash works differently. I'll look again. – Mr.Wizard – 2012-10-23T16:03:27.963

I tried another one and it also did not match. Then I tried one from the picture in your answer and it did. Would you please post the inputhash value you get for several addresses? – Mr.Wizard – 2012-10-23T16:07:07.820

Alternatively: input = StringInsert[#, "+" <> ToString[RandomInteger[99999]], StringPosition[#, "@"][[1, 1]]] & @ email. If one wants slightly more generality, one can insert an arbitrary alphanumeric string of length n like so: StringInsert[#, "+" <> StringJoin[RandomChoice[CharacterRange["a", "z"] ~Join~ CharacterRange["0", "9"], n]], StringPosition[#, "@"][[1, 1]]] & @ "gmailuser@gmail.com" – J. M.'s ennui – 2012-10-23T16:14:59.230

@Mr.Wizard Here it works. For the first image in VLCs post I get d9c48b644b8cc89bbcd07ec7a54dafc9 as hash. Btw, nice work VLC +1. – halirutan – 2012-10-23T16:18:14.587

@Mr.Wizard On OsX you can get the hash by typing this in Terminal: echo -n "gmailuser+10511@gmail.com" |md5. – VLC – 2012-10-23T16:25:45.703

@halirutan please confirm the discrepancy. For IntegerString[Hash["gmailuser+10511@gmail.com", "MD5"], 16, 32] I get "cc270b8fbfb33469629c14e358183dd7". – Mr.Wizard – 2012-10-23T16:28:19.570

@Mr.Wizard The discrepancy is there, on v8 I get d9c48b644b8cc89bbcd07ec7a54dafc9. – VLC – 2012-10-23T16:59:23.307

@Mr.Wizard The differences are also in the documentation for Hash in version 7 and 8. Same examples, different outputs.

– VLC – 2012-10-23T17:04:35.583

@Mr.Wizard See update if it works on v7. – VLC – 2012-10-23T17:18:10.533

That works. Go post an answer. – Mr.Wizard – 2012-10-23T17:23:07.380

@J.M. Good suggestion for those who want to increase the search space. By replacing RandomSample with RandomChoice we can expand it even more. – VLC – 2012-10-24T05:32:24.227