{"id":13558843,"url":"https://github.com/multiformats/multihash","last_synced_at":"2025-05-13T22:00:14.446Z","repository":{"id":17310994,"uuid":"20081715","full_name":"multiformats/multihash","owner":"multiformats","description":"Self describing hashes - for future proofing","archived":false,"fork":false,"pushed_at":"2025-04-28T16:23:20.000Z","size":958,"stargazers_count":918,"open_issues_count":38,"forks_count":118,"subscribers_count":56,"default_branch":"master","last_synced_at":"2025-04-29T13:18:01.922Z","etag":null,"topics":["hash-functions","multiformats","multihash","protocol","varint"],"latest_commit_sha":null,"homepage":"https://multiformats.io/multihash/","language":"Shell","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/multiformats.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,"zenodo":null}},"created_at":"2014-05-23T00:30:31.000Z","updated_at":"2025-04-28T16:23:20.000Z","dependencies_parsed_at":"2024-04-16T06:37:54.368Z","dependency_job_id":"abe645c0-e016-459b-805f-6934e902ccb4","html_url":"https://github.com/multiformats/multihash","commit_stats":{"total_commits":82,"total_committers":45,"mean_commits":"1.8222222222222222","dds":0.8292682926829268,"last_synced_commit":"73740a9a5d8303f44e507dea76899eb270debb6b"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiformats%2Fmultihash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiformats%2Fmultihash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiformats%2Fmultihash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/multiformats%2Fmultihash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/multiformats","download_url":"https://codeload.github.com/multiformats/multihash/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254036806,"owners_count":22003651,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["hash-functions","multiformats","multihash","protocol","varint"],"created_at":"2024-08-01T12:05:11.271Z","updated_at":"2025-05-13T22:00:14.013Z","avatar_url":"https://github.com/multiformats.png","language":"Shell","readme":"# multihash\n\n[![](https://img.shields.io/badge/made%20by-Protocol%20Labs-blue.svg?style=flat-square)](https://protocol.ai/)\n[![](https://img.shields.io/badge/project-multiformats-blue.svg?style=flat-square)](https://github.com/multiformats/multiformats)\n[![](https://img.shields.io/badge/freenode-%23ipfs-blue.svg?style=flat-square)](https://webchat.freenode.net/?channels=%23ipfs)\n[![](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)\n\n\u003e Self identifying hashes\n\nMultihash is a protocol for differentiating outputs from various well-established cryptographic hash functions, addressing size + encoding considerations.\n\nIt is useful to write applications that future-proof their use of hashes, and allow multiple hash functions to coexist. See [jbenet/random-ideas#1](https://github.com/jbenet/random-ideas/issues/1) for a longer discussion.\n\n## Table of Contents\n\n- [Table of Contents](#table-of-contents)\n- [Example](#example)\n- [Format](#format)\n- [Implementations](#implementations)\n- [Table for Multihash](#table-for-multihash)\n  - [Other Tables](#other-tables)\n- [Notes](#notes)\n  - [Multihash and randomness](#multihash-and-randomness)\n  - [Insecure / obsolete hash functions](#insecure--obsolete-hash-functions)\n  - [Non-cryptographic hash functions](#non-cryptographic-hash-functions)\n- [Visual Examples](#visual-examples)\n- [Maintainers](#maintainers)\n- [Contribute](#contribute)\n- [License](#license)\n\n## Example\n\nOutputs of `\u003cencoding\u003e.encode(multihash(\u003cdigest\u003e, \u003cfunction\u003e))`:\n\n```\n# sha1 - 0x11 - sha1(\"multihash\")\n111488c2f11fb2ce392acb5b2986e640211c4690073e # sha1 in hex\nCEKIRQXRD6ZM4OJKZNNSTBXGIAQRYRUQA47A==== # sha1 in base32\n5dsgvJGnvAfiR3K6HCBc4hcokSfmjj # sha1 in base58\nERSIwvEfss45KstbKYbmQCEcRpAHPg== # sha1 in base64\n\n# sha2-256 0x12 - sha2-256(\"multihash\")\n12209cbc07c3f991725836a3aa2a581ca2029198aa420b9d99bc0e131d9f3e2cbe47 # sha2-256 in hex\nCIQJZPAHYP4ZC4SYG2R2UKSYDSRAFEMYVJBAXHMZXQHBGHM7HYWL4RY= # sha256 in base32\nQmYtUc4iTCbbfVSDNKvtQqrfyezPPnFvE33wFmutw9PBBk # sha256 in base58\nEiCcvAfD+ZFyWDajqipYHKICkZiqQgudmbwOEx2fPiy+Rw== # sha256 in base64\n```\n\nNote: You should consider using [multibase](https://github.com/multiformats/multibase) to base-encode these hashes instead of base-encoding them directly.\n\n## Format\n\n```\n\u003cvarint hash function code\u003e\u003cvarint digest size in bytes\u003e\u003chash function output\u003e\n```\n\nBinary example (only 4 bytes for simplicity):\n\n```\nfn code  dig size hash digest\n-------- -------- -----------------------------------\n00010001 00000100 10110110 11111000 01011100 10110101\nsha1     4 bytes  4 byte sha1 digest\n```\n\n\u003e Why have digest size as a separate number?\n\nBecause otherwise you end up with a function code really meaning \"function-and-digest-size-code\". Makes using custom digest sizes annoying, and is less flexible.\n\n\u003e Why isn't the size first?\n\nBecause aesthetically I prefer the code first. You already have to write your stream parsing code to understand that a single byte already means \"a length in bytes more to skip\". Reversing these doesn't buy you much.\n\n\u003e Why varints?\n\nSo that we have no limitation on functions or lengths.\n\n\u003e What kind of varints?\n\nA Most Significant Bit unsigned varint (also called base-128 varints), as defined by the [multiformats/unsigned-varint](https://github.com/multiformats/unsigned-varint).\n\n\u003e Don't we have to agree on a table of functions?\n\nYes, but we already have to agree on functions, so this is not hard. The table even leaves some room for custom function codes.\n\n## Implementations\n\n\u003c!-- Note: Please add implementations to this list alphabetically. Thanks! --\u003e\n\n- [clj-multihash](//github.com/multiformats/clj-multihash)\n- [cpp-multihash](//github.com/cpp-ipfs/cpp-multihash)\n- [dart-multihash](https://github.com/dwyl/dart_multihash)\n- elixir-multihash\n  - [elixir-multihash](//github.com/zabirauf/ex_multihash)\n  - [elixir-multihashing](//github.com/candeira/ex_multihashing)\n- [go-multihash](//github.com/multiformats/go-multihash)\n- [haskell-multihash](//github.com/LukeHoersten/multihash)\n- js-multihash\n  - [js-multiformats](//github.com/multiformats/js-multiformats)\n  - [js-multihash](//github.com/multiformats/js-multihash) (archived)\n- java-multihash\n  - [multiformats/java-multihash](//github.com/multiformats/java-multihash)\n  - [copper multicodec and multihash](https://github.com/filip26/copper-multicodec)\n- kotlin-multihash\n  - [kotlin-multihash](//github.com/changjiashuai/kotlin-multihash)\n  - [multiformat](https://github.com/erwin-kok/multiformat)\n- net-multihash\n  - [cs-multihash](//github.com/multiformats/cs-multihash)\n  - [MultiHash.Net](//github.com/MCGPPeters/MultiHash.Net)\n  - [net-ipfs-core](//github.com/richardschneider/net-ipfs-core)\n- [nim-libp2p](//github.com/status-im/nim-libp2p)\n- [ocaml-multihash](//github.com/patricoferris/ocaml-multihash)\n- [php-multihash](//github.com/Fil/php-multihash)\n- python-multihash\n  - [multiformats/py-multihash](//github.com/multiformats/py-multihash)\n  - [ivilata/pymultihash](//github.com/ivilata/pymultihash)\n  - `multihash` sub-module of Python module [multiformats](//github.com/hashberg-io/multiformats)\n- [ruby-multihash](//github.com/neocities/ruby-multihash)\n- rust-multihash\n  - [by @multiformats](//github.com/multiformats/rust-multihash)\n  - [by @google](//github.com/google/rust-multihash)\n- [scala-multihash](//github.com/mediachain/scala-multihash)\n- swift-multihash\n  - [by @multiformats](//github.com/multiformats/SwiftMultihash)\n  - [by @yeeth](//github.com/yeeth/Multihash.swift)\n  - [by @ATProtoKit](https://github.com/ATProtoKit/MultiformatsKit)\n- [zig-multihash](https://github.com/zen-eth/multiformats-zig)\n\n## Table for Multihash\n\nWe use a single [Multicodec](https://github.com/multiformats/multicodec) [table](https://github.com/multiformats/multicodec/blob/master/table.csv) across all of our multiformat projects. The shared namespace reduces the chances of accidentally interpreting a code in the wrong context. Multihash entries are identified with a `multihash` value in the `tag` column.\n\n### Other Tables\n\nCannot find a good standard on this. Found some _different_ IANA ones:\n\n- https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-18\n- http://tools.ietf.org/html/rfc6920#section-9.4\n\nThey disagree. :(\n\n## Notes\n\n### Multihash and randomness\n\n**Obviously multihash values bias the first two bytes**. Do not expect them to be uniformly distributed. The entropy size is `len(multihash) - 2`. Skip the first two bytes when using them with bloom filters, etc. Why not _ap_pend instead of _pre_pend? Because when reading a stream of hashes, you can know the length of the whole value, and allocate the right amount of memory, skip it, or discard it.\n\n### Insecure / obsolete hash functions\n\n**Obsolete and deprecated hash functions are included** in this list. [MD4](https://en.wikipedia.org/wiki/MD4), [MD5](https://en.wikipedia.org/wiki/MD5) and [SHA-1](https://en.wikipedia.org/wiki/SHA-1) should no longer be used for cryptographic purposes, but since many such hashes already exist they are included in this specification and may be implemented in multihash libraries.\n\n### Non-cryptographic hash functions\n\nMultihash is intended for *\"well-established cryptographic hash functions\"* as **non-cryptographic hash functions are not suitable for content addressing systems**. However, there may be use-cases where it is desireable to identify non-cryptographic hash functions or their digests by use of a multihash. Non-cryptographic hash functions are identified in the [Multicodec table](https://github.com/multiformats/multicodec/blob/master/table.csv) with a tag `hash` value in the `tag` column.\n\n## Visual Examples\n\nThese are visual aids that help tell the story of why Multihash matters.\n\n![](https://raw.githubusercontent.com/multiformats/multihash/master/img/multihash.001.jpg)\n\n#### Consider these 4 different hashes of same input\n\n![](https://raw.githubusercontent.com/multiformats/multihash/master/img/multihash.002.jpg)\n\n#### Same length: 256 bits\n\n![](https://raw.githubusercontent.com/multiformats/multihash/master/img/multihash.003.jpg)\n\n#### Different hash functions\n\n![](https://raw.githubusercontent.com/multiformats/multihash/master/img/multihash.004.jpg)\n\n#### Idea: self-describe the values to distinguish\n\n![](https://raw.githubusercontent.com/multiformats/multihash/master/img/multihash.005.jpg)\n\n#### Multihash: fn code + length prefix\n\n![](https://raw.githubusercontent.com/multiformats/multihash/master/img/multihash.006.jpg)\n\n#### Multihash: a pretty good multiformat\n\n![](https://raw.githubusercontent.com/multiformats/multihash/master/img/multihash.007.jpg)\n\n#### Multihash: has a bunch of implementations already\n\n![](https://raw.githubusercontent.com/multiformats/multihash/master/img/multihash.008.jpg)\n\n## Contribute\n\nContributions welcome. Please check out [the issues](https://github.com/multiformats/multihash/issues).\n\nCheck out our [contributing document](https://github.com/multiformats/multiformats/blob/master/contributing.md) for more information on how we work, and about contributing in general. Please be aware that all interactions related to multiformats are subject to the IPFS [Code of Conduct](https://github.com/ipfs/community/blob/master/code-of-conduct.md).\n\nSmall note: If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.\n\n## License\n\nThis repository is only for documents. All of these are licensed under the [CC-BY-SA 3.0](https://ipfs.io/ipfs/QmVreNvKsQmQZ83T86cWSjPu2vR3yZHGPm5jnxFuunEB9u) license © 2016 Protocol Labs Inc. Any code is under a [MIT](LICENSE) © 2016 Protocol Labs Inc.\n","funding_links":[],"categories":["Shell","others"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmultiformats%2Fmultihash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmultiformats%2Fmultihash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmultiformats%2Fmultihash/lists"}