programming

Generating Github Like Identicons

Written by Rohit Pal

Github introduced user display images as Identicons way back in 2013. Github's Identicons are simple 5x5 pixel colored image displaying identity of a user into his display picture.

Initially Identicons were mostly recognized online as Gravatar, short for Globally recognized avatar, sometimes also regarded as digital-fingerprint, is an image which you could generate that would recognize you to any website as an introduction with some basic details.

Gravatar was a service which would let you create a profile with details like your email, image and few basic details and would give you a url which would let you display or embed profile details in any website.  

Algorithm takes email as user identity (or IP Address) and create a MD5 hash and then hexify that to generate a string which as a url would recognize the user.

The most basic image request URL looks like this: https://www.gravatar.com/avatar/{HASH}

Gravatars on Stackoverflow

where HASH is replaced with the calculated hash for the specific email address you are requesting. This URL generated could be used as an IMG tag to display user image:

https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50

In this post, we would generate user identicon in Github's style; which could be used further to generate user images to identicons as service, into your projects.

Github Identicon Algorithm

Take a user identifier (say email), hash it SHA1 and then convert it to hex binary. Then in order to create a symmetric image rotate it and then mirror the matrix.

Input => someone@email.com (User Identity)

fn MD5Hex(_) => 23adaae0eafc12761c29d920c5da1aa8
// then
fn toInt16(_) => 47424713038463833496632231788185000616
// then
fn toBinary15Limit(_) => 001101010101000

Resultant matrix can be used to draw an image with color pixel on position where pixel value is 1. If you have noticed, we have just expressed the user identifier in a 2D domain.

Generating Identicon Matrix

Now we can use any drawing library like Canvas in NodeJS or PIL(Pillow) in Python to draw the identicon. Let's do this via NodeJS Canvas API. Here's the snippet to generate image from matrix.

const { createCanvas } = require('canvas');
const fs = require('fs');

const SIZE = 350;
const matrix = [
    [0, 1, 0, 1, 0],
    [0, 0, 1, 0, 0],
    [1, 1, 0, 1, 1],
    [1, 0, 0, 0, 1],
    [0, 1, 0, 1, 0]];
const canvas = createCanvas(SIZE, SIZE);

const ctx = canvas.getContext('2d');
ctx.fillStyle = '#f2f2f2';
ctx.fillRect(0, 0, canvas.width, canvas.height);

for (let i = 0; i < matrix.length; i++) {
    for (let j = 0; j < matrix[i].length; j++) {
        if (matrix[i][j] === 1) {
            ctx.fillStyle = '#03a4f4';
            ctx.fillRect((j + 1) * 50, (i + 1) * 50, 50, 50);
        }
    }
}

fs.writeFileSync('out.png', canvas.toBuffer());
Generated output via Canvas API


Hope you liked the post. Cheers!