{"id":18721052,"url":"https://github.com/mauricius/identicon","last_synced_at":"2026-04-28T12:02:44.176Z","repository":{"id":44077527,"uuid":"205405560","full_name":"mauricius/identicon","owner":"mauricius","description":"Identicon service built as a JavaScript Cloudflare Worker","archived":false,"fork":false,"pushed_at":"2023-07-12T02:07:01.000Z","size":784,"stargazers_count":3,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-19T15:12:30.546Z","etag":null,"topics":["cloudflare-worker","identicon","javascript","webpack"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mauricius.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-30T15:09:13.000Z","updated_at":"2023-09-11T15:11:40.000Z","dependencies_parsed_at":"2024-12-28T11:41:19.171Z","dependency_job_id":null,"html_url":"https://github.com/mauricius/identicon","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mauricius/identicon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauricius%2Fidenticon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauricius%2Fidenticon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauricius%2Fidenticon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauricius%2Fidenticon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mauricius","download_url":"https://codeload.github.com/mauricius/identicon/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mauricius%2Fidenticon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32379629,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-28T11:25:28.583Z","status":"ssl_error","status_checked_at":"2026-04-28T11:25:05.435Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudflare-worker","identicon","javascript","webpack"],"created_at":"2024-11-07T13:33:24.381Z","updated_at":"2026-04-28T12:02:44.150Z","avatar_url":"https://github.com/mauricius.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Identicon :cloud: :sparkles: :construction_worker:\n\n[Identicon](https://en.wikipedia.org/wiki/Identicon) service built as a JavaScript [Cloudflare Worker](https://workers.cloudflare.com/). Algorithm implementation inspired by [the original Java code by Don Park](https://web.archive.org/web/20080703155749/http://www.docuverse.com/blog/donpark/2007/01/19/identicon-updated-and-source-released).\n\n[Demo](https://identicon.mauricius.workers.dev/6b3eb288cd0ac76efa64097b38a81cb6e23ae031)\n\n## About Cloudflare Workers\n\n\u003e Cloudflare Workers provides a serverless execution environment that allows you to create entirely new applications or augment existing ones without configuring or maintaining infrastructure.\n\n[Documentation](https://workers.cloudflare.com/docs)\n\n### Instructions\n\n- `npm install`\n- `npm run build`\n\nTo open the Workers preview with the built Worker:\n\n- `npm run preview`\n\nor you can use [Wrangler](https://github.com/cloudflare/wrangler)\n\n- `wrangler build`\n- `wrangler preview`\n\n## About the Identicon Algorithm\n\nAn Identicon is a visual representation of a hash value, usually derived from an IP address. The input of this algorithm is a `SHA-1` string, from which the first 4 bytes (32 bits) are extracted to serve as source for the Identicon.\n\n`11111111 11111111 11111111 11111111`\n\nThe generated Identicon is a **3x3** grid, built using only 3 types of patches, out of [16 available](#patches), in 9 positions.\n\n- one patch for the center position\n- one patch for the 4 **S**ides\n- one patch for the 4 **C**orners\n\n```\n┌──┬──┬──┐\n│C │S │ C│\n├──┼──┼──┤\n│S │  │ S│\n├──┼──┼──┤\n│C │ S│ C│\n└──┴──┴──┘\n```\n\n### Positions and Rotations\n\nFor center position, only a symmetric patch is selected (out of 4 available). For corner and side positions, patch is rotated by 90° moving clock-wise starting from top-left position and top position respectively. This means 2 bits out of identicon code are used to select the center patch, 4 bits each for corner and side patches, 2 bits each for starting rotation of corner and side patches.\n\n### Coloring and Inverting\n\nThe background is always white. The patch color is selected using 15 bits from the identicon code, expending 5 bits for each color component (Red, Green, Blue) placed at high-end of the component value (bits \u003c\u003c 3). 1 bit per patch is used for inversion, meaning selected color will be used as background and white used as the patch shape color.\n\nAdding it up, we are using 32 bits (actually 31, more on that later) to render an identicon.\n\n| 11111 | 11111 | 11111 |   11   |   1    | 1111  |   11   |   1    |  1111  |   1    |   11   |\n| :---: | :---: | :---: | :----: | :----: | :---: | :----: | :----: | :----: | :----: | :----: |\n|  red  | green | blue  |  side  |  side  | side  | corner | corner | corner | middle | middle |\n| color | color | color | rotate | invert | shape | rotate | invert | shape  | invert | shape  |\n\n### Potential Combinations\n\n#### Center\n\n- `2² = 4` pattern choices\n- `2¹ = 2` color choices (inverted or not)\n\n#### Edges\n\n- `2⁴ = 16` pattern choices\n- `2¹ = 2` color choices (inverted or not)\n- `2² = 4` pattern rotation choices (some may be identical)\n\n  - `0` - no rotation\n  - `1` - 90° rotation\n  - `2` - 180° rotation\n  - `3` - 270° rotation\n\n#### Corners\n\n- `2⁴ = 16` pattern choices\n- `2¹ = 2` color choices (inverted or not)\n- `2² = 4` pattern rotation choices (some may be identical)\n\n#### Colors\n\n- `2⁵ = 32` choices for red color\n- `2⁵ = 32` choices for green color\n- `2⁵ = 32` choices for blue color\n\n### Patches\n\n![](patches.png)\n\nThere are 16 potential patterns to use to create the identicon. Using a **5x5** grid like the following\n\n```\n┌──┬──┬──┬──┬──┐\n│ 0│ 1│ 2│ 3│ 4│\n├──┼──┼──┤──┤──┤\n│ 5│ 6│ 7│ 8│ 9│\n├──┼──┼──┼──┼──┤\n│10│11│12│13│14│\n├──┼──┼──┼──┼──┤\n│15│16│17│18│19│\n├──┼──┼──┼──┼──┤\n│20│21│22│23│24│\n└──┴──┴──┴──┴──┘\n```\n\nwe can define each pattern using an array to stores the vertices.\n\n```\nconst shape1 = [0, 4, 24, 20];\n┌ ─ ─ ─ ┐\n│       │\n│       │\n│       │\n└ ─ ─ ─ ┘\n```\n\n```\nconst shape2 = [0, 4, 20];\n┌ ─ ─ ─ ─\n│      ╱\n│    ╱\n│  ╱\n|╱\n```\n\n```\nconst shape3  = [2, 24, 20];\n   ╱╲\n  ╱  ╲\n ╱    ╲\n╱______╲\n```\n\n```\nconst shape4  = [0, 2, 20, 22];\n_____\n╲   ╱\n ╲ ╱\n ╱ ╲\n╱___╲\n```\n\n```\nconst shape5  = [2, 14, 22, 10];\n\n  / \\\n /   \\\n \\   /\n  \\ /\n```\n\n```\nconst shape6  = [0, 14, 24, 22];\n\\\n\\ \\\n \\  \\\n  \\   \\\n   ───┘\n```\n\n```\nconst shape7  = [2, 24, 22, 13, 11, 22, 20];\n   /\\\n  /__\\\n ╱\\  /\\\n╱__\\/__\\\n```\n\n```\nconst shape8  = [0, 14, 22];\n \\\n\\  \\\n \\   \\\n  \\  /\n   \\/\n```\n\n```\nconst shape9  = [6, 8, 18, 16];\n\n  ┌ ─ ┐\n  │   │\n  └ ─ ┘\n\n```\n\n```\nconst shape10  = [4, 20, 10, 12, 2];\n     ___\n    |  ╱\n ___|╱\n│  ╱\n|╱\n```\n\n```\nconst shape11 = [0, 2, 12, 10];\n┌ ─ ┐\n│   │\n└ ─ ┘\n\n\n```\n\n```\nconst shape12 = [10, 14, 22];\n\n______\n\\    /\n \\  /\n  \\/\n```\n\n```\nconst shape13 = [20, 12, 24];\n\n\n  /\\\n /  \\\n/____\\\n```\n\n```\nconst shape14 = [10, 2, 12];\n  /|\n/__|\n\n\n\n```\n\n```\nconst shape15 = [0, 2, 10];\n ___\n|  ╱\n|╱\n\n\n```\n\nNote that the 16th shape is just an inverted version of the first one.\n\n## Example\n\nLet's try to recreate the Identicon of my GitHub username:\n\n\u003cp style=\"text-align: center\"\u003e\n  \u003cimg src=\"mauricius.png\"\u003e\n\u003c/p\u003e\n\nBefore starting we need to remember two important notions:\n\n- The maximum number in 32-bits space is `parseInt(\"1111111111111111111111111111111\", 2) = 2147483647` (or `2³¹ - 1`, since the first bit is the sign bit).\n- Numbers in JavaScript are represented by 64-bit values, but bitwise operators always return a 32-bit integer.\n\n### Hash the input\n\n`'mauricius'` after the SHA-1 hashing process becomes `6b3eb288cd0ac76efa64097b38a81cb6e23ae031`. We take the first 4 bytes and convert the value to an integer. In this case it is `1799271048`.\n\n`1799271048` in binary is `1101011001111101011001010001000`.\n\n### Center Patch\n\n#### Take the shape\n\nThe last two bits define the shape in the center (4 available options)\n\n```\n1101011001111101011001010001000 \u0026\n0000000000000000000000000000011\n---------------------------------\n0000000000000000000000000000000\n```\n\nWe need to take the shape of index 0, which is the square.\n\n#### Invert\n\nWe right-shift the binary representation of `1799271048` of two positions:\n\n```\n1101011001111101011001010001000 \u003e\u003e 2\n0011010110011111010110010100010\n```\n\nor `449817762` in decimal. We take the last bit\n\n```\n11010110011111010110010100010 \u0026\n00000000000000000000000000001\n-------------------------------\n00000000000000000000000000000\n```\n\nSince `0` is `false` we do not invert the colors of the center shape. This is the result\n\n\u003cp style=\"text-align: center\"\u003e\n  \u003cimg src=\"step1.png\"\u003e\n\u003c/p\u003e\n\n### Corner patches\n\n#### Take the shape\n\nAgain, we need to right-shift the binary representation of `1799271048` of 3 positions:\n\n```\n1101011001111101011001010001000 \u003e\u003e 3\n0001101011001111101011001010001\n```\n\nor `224908881` in decimal. We take the last 4 bits:\n\n```\n0001101011001111101011001010001 \u0026\n0000000000000000000000000001111\n---------------------------------\n0000000000000000000000000000001\n```\n\nSince `2⁰ = 1`, we take the shape 2 which has index 1.\n\n#### Invert\n\nWe shift the binary representation of `1799271048` of 7 positions:\n\n```\n1101011001111101011001010001000 \u003e\u003e 7\n0000000110101100111110101100101\n```\n\nor `14056805` in decimal. We take the last bit:\n\n```\n0000000110101100111110101100101 \u0026\n0000000000000000000000000000001\n---------------------------------\n0000000000000000000000000000001\n```\n\nSince `1` is `true` we invert the colors of the corner shape.\n\n#### Rotate\n\nWe shift the binary representation of `1799271048` of 8 positions:\n\n```\n1101011001111101011001010001000 \u003e\u003e 8\n0000000011010110011111010110010\n```\n\nor `7028402` in decimal. We take the last 3 bits:\n\n```\n0000000011010110011111010110010 \u0026\n0000000000000000000000000000111\n---------------------------------\n0000000000000000000000000000010\n```\n\nSince `2¹ = 2`, we start with the patch rotated by 180° in the upper-left corner and we keep rotating for every corner.\n\n\u003cp style=\"text-align: center\"\u003e\n  \u003cimg src=\"step2.png\"\u003e\n\u003c/p\u003e\n\n### Edge patches\n\n#### Take the shape\n\nWe need to shift the binary representation of `1799271048` of 10 positions:\n\n```\n1101011001111101011001010001000 \u003e\u003e 10\n0000000000110101100111110101100\n```\n\nor `1757100` in decimal. We take the last 4 bits:\n\n```\n0000000000110101100111110101100 \u0026\n0000000000000000000000000001111\n---------------------------------\n0000000000000000000000000001100\n```\n\nSince `2³ + 2² = 12`, we take the shape 13 which has index 12.\n\n#### Invert\n\nWe shift the binary representation of `1799271048` of 14 positions:\n\n```\n1101011001111101011001010001000 \u003e\u003e 14\n0000000000000011010110011111010\n```\n\nor `109818` in decimal. We take the last bit:\n\n```\n0000000000000011010110011111010 \u0026\n0000000000000000000000000000001\n---------------------------------\n0000000000000000000000000000000\n```\n\nSince `0` is `false` we do not invert the colors of the edge shapes.\n\n#### Rotate\n\nWe shift the binary representation of `1799271048` of 15 positions:\n\n```\n1101011001111101011001010001000 \u003e\u003e 15\n0000000000000001101011001111101\n```\n\nor `54909` in decimal. We take the last 2 bits:\n\n```\n0000000000000001101011001111101 \u0026\n0000000000000000000000000000011\n---------------------------------\n0000000000000000000000000000001\n```\n\nSince `2⁰ = 1` we start with the patch rotated by 90° in the top edge and we keep rotating it for every edge.\n\n\u003cp style=\"text-align: center\"\u003e\n  \u003cimg src=\"step3.png\"\u003e\n\u003c/p\u003e\n\n### Colors\n\n#### :blue_heart: Blue\n\nWe shift the binary representation of `1799271048` of 17 positions:\n\n```\n1101011001111101011001010001000 \u003e\u003e 17\n0000000000000000011010110011111\n```\n\nor `13727` in decimal. We take the last 5 bits:\n\n```\n0000000000000000011010110011111 \u0026\n0000000000000000000000000011111\n---------------------------------\n0000000000000000000000000011111\n```\n\nand we left shift this last value in order to get a number in the 0-255 range.\n\n```\n0000000000000000000000000011111 \u003c\u003c 3\n0000000000000000000000011111000\n```\n\nor `248` in decimal.\n\nSince using [left-shifting](\u003chttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#%3C%3C_(Left_shift)\u003e) means that zero bits are shifted in from the right, the maximum value that we can obtain in the 0-255 range is exactly `248`. This isn't valid for the [Red color](#red), as we will see later.\n\n#### :green_heart: Green\n\nWe shift the binary representation of `1799271048` of 22 positions:\n\n```\n1101011001111101011001010001000 \u003e\u003e 22\n0000000000000000000000110101100\n```\n\nor `428` in decimal. We take the last 5 bits:\n\n```\n0000000000000000000000110101100 \u0026\n0000000000000000000000000011111\n---------------------------------\n0000000000000000000000000001100\n```\n\nand we left shift this last value in order to get a number in the 0-255 range.\n\n```\n0000000000000000000000000001100 \u003c\u003c 3\n0000000000000000000000001100000\n```\n\nor `96` in decimal.\n\n#### :heart: Red\n\nWe have only 4 bits left for the red color. Since we are using the [sign-propagating right shift operator](\u003chttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#%3E%3E_(Sign-propagating_right_shift)\u003e), we will always use the sign bit (which is `0` because we are using positive values) to build the red color.\n\nWe right-shift the binary representation of `1799271048` of 27 positions:\n\n```\n1101011001111101011001010001000 \u003e\u003e 27\n0000000000000000000000000001101\n```\n\nor `13` in decimal. We take the last 5 bits:\n\n```\n0000000000000000000000000001101 \u0026\n0000000000000000000000000011111\n---------------------------------\n0000000000000000000000000001101\n```\n\nand we left shift this last value in order to get a number in the 0-255 range.\n\n```\n0000000000000000000000000001101 \u003c\u003c 3\n0000000000000000000000001101000\n```\n\nor `104` in decimal.\n\nThe maximum red value that we can obtain in the 0-255 range is `120`. This means that the identicon will always be colored towards the Blue channel.\n\nThe foreground color will then be `rgb(104,96,248)`.\n\n\u003cp style=\"text-align: center\"\u003e\n  \u003cimg src=\"mauricius.png\"\u003e\n\u003c/p\u003e\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmauricius%2Fidenticon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmauricius%2Fidenticon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmauricius%2Fidenticon/lists"}