{"id":13674065,"url":"https://github.com/0xflotus/hashpic","last_synced_at":"2026-01-14T09:59:56.306Z","repository":{"id":43222498,"uuid":"454641855","full_name":"0xflotus/hashpic","owner":"0xflotus","description":"Hashpic creates an image from a MD5, SHA512, SHA3-512, Blake2b or SHAKE256 hash","archived":false,"fork":false,"pushed_at":"2025-11-12T09:50:05.000Z","size":5616,"stargazers_count":26,"open_issues_count":2,"forks_count":6,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-11-12T11:29:58.138Z","etag":null,"topics":["art","blake2b","hacktoberfest","hacktoberfest-accepted","hash","hex","md5","png","python","sha3","sha512","shake256","svg"],"latest_commit_sha":null,"homepage":"","language":"Python","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/0xflotus.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":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-02-02T04:25:24.000Z","updated_at":"2025-11-12T09:50:02.000Z","dependencies_parsed_at":"2023-11-24T10:47:46.328Z","dependency_job_id":"b3d595a8-11e1-45c7-9c35-69b4a3677f76","html_url":"https://github.com/0xflotus/hashpic","commit_stats":{"total_commits":281,"total_committers":2,"mean_commits":140.5,"dds":"0.017793594306049876","last_synced_commit":"21db665cea1943ab2d123579b767e5c941ecd144"},"previous_names":[],"tags_count":58,"template":false,"template_full_name":null,"purl":"pkg:github/0xflotus/hashpic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xflotus%2Fhashpic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xflotus%2Fhashpic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xflotus%2Fhashpic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xflotus%2Fhashpic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0xflotus","download_url":"https://codeload.github.com/0xflotus/hashpic/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0xflotus%2Fhashpic/sbom","scorecard":{"id":772,"data":{"date":"2025-08-11","repo":{"name":"github.com/0xflotus/hashpic","commit":"506d54c6dfbc2be4cd9c5c70c109af02592d849e"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.9,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/11 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":2,"reason":"3 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":9,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:28","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:29","Warn: no topLevel permission defined: .github/workflows/codeql.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/0xflotus/hashpic/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/0xflotus/hashpic/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/0xflotus/hashpic/codeql.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:74: update your workflow using https://app.stepsecurity.io/secureworkflow/0xflotus/hashpic/codeql.yml/main?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1: pin your Docker image by updating python:3.12-alpine to python:3.12-alpine@sha256:9b8808206f4a956130546a32cbdd8633bc973b19db2923b7298e6f90cc26db08","Warn: pipCommand not pinned by hash: Dockerfile:11","Warn: pipCommand not pinned by hash: Dockerfile:12","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned","Info:   0 out of   2 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 0 commits out of 23 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-14T12:27:55.055Z","repository_id":43222498,"created_at":"2025-08-14T12:27:55.055Z","updated_at":"2025-08-14T12:27:55.055Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28416469,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T08:38:59.149Z","status":"ssl_error","status_checked_at":"2026-01-14T08:38:43.588Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["art","blake2b","hacktoberfest","hacktoberfest-accepted","hash","hex","md5","png","python","sha3","sha512","shake256","svg"],"created_at":"2024-08-02T11:00:37.655Z","updated_at":"2026-01-14T09:59:56.291Z","avatar_url":"https://github.com/0xflotus.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# Hashpic\n\nHashpic creates an image from the *MD5* hash of your input.\n\nSince _v0.2.0_ it is also possible to create an image from a *SHA-512* hash.\n\nSince _v0.4.8_ it is also possible to create an image from a *SHAKE-256* hash with variable digest length of _4_, _9_, _16_, _25_, _36_, _64_, _100_, _144_, _225_ or _255_.\n\nSince _v0.3.5_ it is also possible to create an image from a *SHA3-512* and a *BLAKE2b* hash.\n\nSince _v0.4.0_ it is possible to create an image as *SVG*.\n\n_v0.6.0_ brought a huge performance boost.\n\n## Requirements\n\nMake sure you have installed the [dependencies for Pillow](https://pillow.readthedocs.io/en/latest/installation.html#building-from-source)\n\nOn MacOS:\n\n```sh\nbrew install libjpeg libtiff little-cms2 openjpeg webp\n```\n\n## Install\n\n`pip3 install hashpic`\n\n## Usage\n\n```bash\npython3 -m hashpic 'Hashpic rocks!'\n```\n\nThis should create a file `output.png` in your current directory. \nThe input `Hashpic rocks!` should create the following image:\n\n![hashpic image](./docs/rocks.png)\n\n## Piping from another program\n\nAll this commands should produce the same image as above.\n\n```bash\nprintf 'Hashpic rocks!' | md5 | python3 -m hashpic --bypass\n\nprintf 'Hashpic rocks!' | python3 -m hashpic\n```\n\n## SVG Mode 🎉🎉🎉\n\nSince _v0.4.0_ it is possible to create an image as *SVG*. The following command will create a file `output.svg` in your current directory. \n\n```bash\npython3 -m hashpic 'Hashpic rocks!' --svg\n```\n\n![svg](./docs/rocks_on_svg.svg)\n\nSince _v0.5.0_ it is possible to create circles instead of squares. But this is limited to the `SVG Mode`.\n\n```bash\npython3 -m hashpic 'Hashpic rocks!' --svg --round\n```\n\n![rounded](./docs/rounded.svg)\n\nSince _v0.7.0_ it is possible to create hexagons instead of squares. But this is limited to the `SVG Mode`. \nIf you pass also the `--round` flag when using `--hexagon`, `--round` will be ignored.\n\n```bash\npython3 -m hashpic 'Hashpic rocks!' --svg --hexagon\n```\n\n![rounded](./docs/hexagon_md5.svg)\n\nSince _v0.5.2_ it is possible to add a background color to the SVG.\n\n```bash\npython3 -m hashpic 'Hashpic rocks!' --svg --round --background '#000000'\n```\n\n## Console Mode\n\n![console](./docs/console.png)\n\n## Hashing a file\n\nIt is also possible to create an image from a hash of a file. Use the `--file` argument for that.\n\n```bash\npython3 -m hashpic --file README.md\n```\n\n## SHA-512 Mode\n\nIt is also possible to create an image from a *SHA-512* hash. All arguments for *MD5 Mode* are also available for *SHA512 Mode*.\n\n```bash\npython3 -m hashpic --sha512 'Hashpic rocks!'\n\nprintf 'Hashpic rocks!' | python3 -m hashpic --sha512\n```\n\nThis commands should create the following image:\n\n![sha512 image](./docs/rocks_on_sha512.png)\n\n## SHAKE256 Mode\n\nYou can create an image from a *SHAKE256* hash with variable digest lengths. Valid lengths are _4_, _9_, _16_, _25_, _36_, _64_, _100_, _144_, _225_ and _255_. You must specify the length of the digest if you want to create an image from a *SHAKE256* hash.\n\n```bash\npython3 -m hashpic --shake256 --length 100 'Hashpic rocks!'\n```\n\nThe command above should produce the following image:\n\n![shake256](./docs/shake256/100.png)\n\n### More SHAKE256 examples\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to see more examples.\u003c/summary\u003e\n\n  ### Digest Length of 4\n  \n  ```bash\n  python3 -m hashpic --shake256 --length 4 'Hashpic rocks!'\n  ```\n\n  ![shake256](./docs/shake256/4.png)\n\n  ### Digest Length of 9\n  \n  ```bash\n  python3 -m hashpic --shake256 --length 9 'Hashpic rocks!'\n  ```\n\n  ![shake256](./docs/shake256/9.png)\n\n  ### Digest Length of 16\n\n  ```bash\n  python3 -m hashpic --shake256 --length 16 'Hashpic rocks!'\n  ```\n  ![shake256](./docs/shake256/16.png)\n\n  ### Digest Length of 25\n\n  ```bash\n  python3 -m hashpic --shake256 --length 25 'Hashpic rocks!'\n  ```\n\n  ![shake256](./docs/shake256/25.png)\n\n  ### Digest Length of 36\n\n  ```bash\n  python3 -m hashpic --shake256 --length 36 'Hashpic rocks!'\n  ```\n\n  ![shake256](./docs/shake256/36.png)\n\n  ### Digest Length of 64\n\n  ```bash\n  python3 -m hashpic --shake256 --length 64 'Hashpic rocks!'\n  ```\n\n  ![shake256](./docs/shake256/64.png)\n\n  ### Digest Length of 100\n\n  ```bash\n  python3 -m hashpic --shake256 --length 100 'Hashpic rocks!'\n  ```\n\n  ![shake256](./docs/shake256/100.png)\n\n  ### Digest Length of 144\n\n  ```bash\n  python3 -m hashpic --shake256 --length 144 'Hashpic rocks!'\n  ```\n\n  ![shake256](./docs/shake256/144.png)\n\n  ### Digest Length of 225\n\n  ```bash\n  python3 -m hashpic --shake256 --length 225 'Hashpic rocks!'\n  ```\n\n  ![shake256](./docs/shake256/225.png)\n\n  ### Digest Length of 255\n\n  It adds a `padding byte of 0xff` to the end of the hash to fit it into a `16x16 grid`. Please keep this in mind.\n\n  ```bash\n  python3 -m hashpic --shake256 --length 255 'Hashpic rocks!'\n  ```\n\n  ![shake256](./docs/shake256/255.png)\n\u003c/details\u003e\n\u003chr/\u003e\n\n## SHA3 Mode\n\nIt is possible to create an image from a *SHA3* hash. \n\n```bash\npython3 -m hashpic 'Hashpic rocks!' --sha3\n```\n\n![sha3](./docs/rocks_on_sha3.png)\n\n## BLAKE2b Mode\n\nIt is possible to create an image from a *BLAKE2b* hash. \n\n```bash\npython3 -m hashpic 'Hashpic rocks!' --blake2b\n```\n\n![sha3](./docs/rocks_on_blake2b.png)\n\n## Using with Docker\n\nSince _v0.4.4_ there is a dockerized version available on [`ghcr.io`](https://github.com/0xflotus/hashpic/pkgs/container/hashpic). You can pull the image from there and use it e.g.:\n\n```bash\ndocker run -it -v \"$(pwd)\":/app --rm ghcr.io/0xflotus/hashpic:0.6.2 deadbeef --bypass --shake256 --length 4\n```\n\nYou can also pipe to docker:\n\n```bash\nprintf 'ff0030ffe589b7a4e1320f12c4c8de73' | docker run -i --rm ghcr.io/0xflotus/hashpic:0.6.2 -c --shake256 --length 16 --bypass\n```\n\n## Examples\n\nBypassing a hash directly:\n\n```bash\npython3 -m hashpic ff00ff00ff00ff0000ff00ff00ff00ffff00ff00ff00ff0000ff00ff00ff00ffff00ff00ff00ff0000ff00ff00ff00ffff00ff00ff00ff0000ff00ff00ff00ff --bypass --sha512\n```\n\nThis command will produce the following image:\n\n![bypassed](./docs/bypassed.png)\n\nSo we can call the hash above the so called `chessboard hash`.\n\n\u003chr\u003e\n\nYou can also bypass a hash from another program:\n\n```bash\nprintf 'Hashpic rocks!' | sha512sum | awk '{print $1}' | python3 -m hashpic --sha512 -c --bypass \n```\n\n![bypassed from another program](./docs/bypassed_pipe.svg)\n\n\u003chr\u003e\n\nWith all this in mind you can also use hashpic to create an image not only from a hash but e.g. from the current time in hex:\n\n```bash\npython3 -c \"import time; print(hex(int(time.time()))[2:])\" | python3 -m hashpic --shake256 --length 4 --bypass\n```\n\nOr e.g. an IP address in hexadecimal form:\n\n```bash\n# localhost hex(127.0.0.1) == 7f000001\npython3 -m hashpic 7f000001 --shake256 --length 4 --bypass\n\n# e.g. an IPv6 address of Googles DNS server\nprintf 2001:4860:4860:0000:0000:0000:0000:8844 | tr -d ':' | python3 -m hashpic --bypass \n```\n\nIf you have installed [`h3`](https://h3geo.org/) you can transform a geo coordinate to an image. \nThe example below uses the geo coordinates of the `Eiffel Tower in Paris, France`.\n\n```bash\npython3 -c \"import h3; print(h3.geo_to_h3(48.8583230030819, 2.294450300083837, 15).zfill(18))\" | python3 -m hashpic --bypass --shake256 --length 9\n```\n\nIt is also possible to create an image from an `uuid`.\n\n```bash\npython3 -c \"import uuid; print(str(uuid.uuid4()).replace('-', ''))\" | python3 -m hashpic --bypass -c\n```\n\nYou can also create an image from any 64-bit integer.\n\n```bash\nprintf 8724325378325383578 | python3 -c \"import sys, textwrap; print(''.join([hex(int(bit))[2:].zfill(2) for bit in textwrap.fill(bin(int(sys.stdin.read()))[2:].zfill(64), 1).split('\\n')]))\" | python3 -m hashpic --bypass --svg --round --sha3\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eClick to see more examples.\u003c/summary\u003e\n\n```bash\n# compute the bypassed number\npython3 -c \"print(2**56-1)\" | python3 -c \"import sys, textwrap; print(''.join([hex(int(bit))[2:].zfill(2) for bit in textwrap.fill(bin(int(sys.stdin.read()))[2:].zfill(64),1).split('\\n')]))\" | python3 -m hashpic --bypass --svg --round --sha3\n\n# bypass the binary directly\nprintf 0110100111001100001101001110011000111110011100110000111100111011 | python3 -c \"import sys, textwrap; print(''.join([hex(int(bit))[2:].zfill(2) for bit in textwrap.fill(bin(int(sys.stdin.read(), 2))[2:].zfill(64),1).split('\\n')]))\" | python3 -m hashpic --bypass --svg --round --sha3\n\n# map the colors \nprintf 0110100111001100001101001110011000111110011100110000111100111011 | python3 -c \"import sys, textwrap; print(''.join(map(lambda x: '00' if x == '01' else 'ff', [hex(int(bit))[2:].zfill(2) for bit in textwrap.fill(bin(int(sys.stdin.read(), 2))[2:].zfill(64),1).split('\\n')])))\" | python3 -m hashpic --bypass --svg --round --sha3\n```\n\n\u003c/details\u003e\n\n## Star History\n\n[![Star History Chart](https://api.star-history.com/svg?repos=0xflotus/hashpic\u0026type=Timeline)](https://star-history.com/#0xflotus/hashpic\u0026Timeline)\n\n## Disclaimer\n\nThe color palette in [`data.py`](./hashpic/data.py) was influenced by the [`string-color`](https://gitlab.com/shindagger/string-color) library. \nThanks for this!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xflotus%2Fhashpic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0xflotus%2Fhashpic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0xflotus%2Fhashpic/lists"}