{"id":13491369,"url":"https://github.com/nocursor/ex-cid","last_synced_at":"2025-04-14T09:23:23.831Z","repository":{"id":57482880,"uuid":"158707472","full_name":"nocursor/ex-cid","owner":"nocursor","description":"Elixir library for creating self-describing content-addressed identifiers for distributed systems (CIDs).","archived":false,"fork":false,"pushed_at":"2019-01-17T16:55:40.000Z","size":15,"stargazers_count":17,"open_issues_count":2,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-09-14T22:10:14.820Z","etag":null,"topics":["cid","codec","decoding","distributed-id","distributed-systems","elixir","elixir-lang","encoding","ipfs","multibase","multicodec","multihash"],"latest_commit_sha":null,"homepage":null,"language":"Elixir","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/nocursor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-22T14:00:31.000Z","updated_at":"2024-06-05T10:26:45.000Z","dependencies_parsed_at":"2022-09-26T17:50:37.581Z","dependency_job_id":null,"html_url":"https://github.com/nocursor/ex-cid","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nocursor%2Fex-cid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nocursor%2Fex-cid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nocursor%2Fex-cid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nocursor%2Fex-cid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nocursor","download_url":"https://codeload.github.com/nocursor/ex-cid/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248852465,"owners_count":21171899,"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":["cid","codec","decoding","distributed-id","distributed-systems","elixir","elixir-lang","encoding","ipfs","multibase","multicodec","multihash"],"created_at":"2024-07-31T19:00:56.250Z","updated_at":"2025-04-14T09:23:23.785Z","avatar_url":"https://github.com/nocursor.png","language":"Elixir","funding_links":[],"categories":["Elixir"],"sub_categories":[],"readme":"# Elixir CID\n\nElixir version of [CID](https://github.com/ipld/cid). CID is currently being used as part of [IPFS](https://ipfs.io/) for identifying distributed content.\n\n\u003e Self-describing content-addressed identifiers for distributed systems\n\n## Motivation\n\n[**CID**](https://github.com/ipld/cid) is a format for referencing content in distributed information systems, like [IPFS](https://ipfs.io). It leverages [content addressing](https://en.wikipedia.org/wiki/Content-addressable_storage), [cryptographic hashing](https://simple.wikipedia.org/wiki/Cryptographic_hash_function), and [self-describing formats](https://github.com/multiformats/multiformats). It is the core identifier used by [IPFS](https://ipfs.io) and [IPLD](https://ipld.io).\n\n## Features\n\n* Encode/Decode CIDs\n    * Encode a CID to a string\n    * Encode a CID buffer to later Multibase encode\n    * Decode a CID string to a CID and optionally, the Multibase encoding used\n* Human readable CIDs for debugging and checking\n* Error handling and exception versions of most major API functions\n* Current support for all Multibase and Multicodec encodings\n* Immutable Elixir struct for CID data\n    * Easy comparisons, construction, validation, etc.\n    * Send over the wire\n    * Simple debugging and inspecting\n* Consistent API\n* Support for CID v0 and CID v1\n* Tests\n\n## Usage\n\nThe following examples show the basic usage of using this library to encode, decode, and introspect CIDs. \n\n*Note*: that in the case of codecs (Multicodec), multihashes (Multihash), and encodings (Multibase), we may select values for demonstration purposes. In other words, some usage may not match reality - pragmatic examples are the goal. \n\nRead more about [Multicodec](https://github.com/multiformats/multicodec), [Multihash](https://github.com/multiformats/multihash), and [Multibase](https://github.com/multiformats/multibase) to learn more.\n\n### Create a CID\n\n```elixir\n# first let's create a Multihash to use for our examples\n{:ok, multihash} = Multihash.encode(:sha2_256, :crypto.hash(:sha256, \"like common people\")) \n{:ok,\n \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92, 130, 235, 240,\n   88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153, 175, 31, 65,\n   149\u003e\u003e}\n\n# the default version is the latest (CID v1) and the default codec is \"dag-pb\" which is used for CID v0\nCID.cid(multihash)\n{:ok,\n %CID{\n   codec: \"dag-pb\",\n   multihash: \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92,\n     130, 235, 240, 88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153,\n     175, 31, 65, 149\u003e\u003e,\n   version: 1\n }}\n\n# we can also use an exception raising version\n# let's also change the codec too and explicitly pass the version\nCID.cid!(multihash, \"cbor\", 1)  \n%CID{\n  codec: \"cbor\",\n  multihash: \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92,\n    130, 235, 240, 88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153,\n    175, 31, 65, 149\u003e\u003e,\n  version: 1\n}\n\n# if for some reason we want a CID v0 ID, we can do it like so\n{:ok, v0_multihash} = Multihash.encode(:sha2_256, :crypto.hash(:sha256, \"like common people\"), 32) \n{:ok,\n \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92, 130, 235, 240,\n   88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153, 175, 31, 65,\n   149\u003e\u003e}\n\nCID.cid!(v0_multihash, \"dag-pb\", 0)\n%CID{\n  codec: \"dag-pb\",\n  multihash: \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92,\n    130, 235, 240, 88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153,\n    175, 31, 65, 149\u003e\u003e,\n  version: 0\n}\n\n# thankfully if we mess up, our lib stops us before catastrophe strikes\nCID.cid(v0_multihash, \"cbor\", 0)   \n{:error, :invalid_multicodec}\n\nCID.cid(multihash, \"barrel of feet\", 1)\n{:error, :invalid_multicodec}\n```\n\n### Encode a CID\n\nNow let's actually encode a CID to a string, for use in an application perhaps like IPFS:\n\n```elixir\nCID.cid!(multihash, \"dag-json\", 1) |\u003e CID.encode()\n{:ok, \"z4EBG9jACDDa7TeGCBUUk4ziuRsGmGnjefMx5GEofptsFxTaH8Q\"}\n\n# we also have our exception raising version\nCID.cid!(multihash, \"cbor\", 1) |\u003e CID.encode!()\n\"zadi4ekZWb9uwiPgSM1Fki5UAfvggkGC27Qy6acaYZ49jycsv\"\n\n# and we can do the same for a v0 CID\nCID.cid!(v0_multihash, \"dag-pb\", 0) |\u003e CID.encode()  \n{:ok, \"QmYR6e57B15cM77ankTPqxsQVbFVzcYSGrFGr5WtmR8jdn\"}\n\n# we can only encode a v0 CID with :base58_btc\nCID.cid!(v0_multihash, \"dag-pb\", 0) |\u003e CID.encode(:base64)    \n{:error, :invalid_encoding}\n\n# with CID v1 we can control the encoding - let's choose :base64\nCID.cid!(multihash, \"dag-pb\", 1) |\u003e CID.encode!(:base64)\n\"mAXASIJW4gxsH5vZxGi3rXILr8Fhj0K2zMchrK63Ip5mvH0GV\"\n\n# if we just want the buffer, we can also do this\nCID.cid!(multihash, \"cbor\", 1) |\u003e CID.encode_buffer()\n{:ok,\n \u003c\u003c1, 81, 18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92, 130,\n   235, 240, 88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153, 175,\n   31, 65, 149\u003e\u003e}\n      \n```\n\n### Decode a CID\n\nDecode a CID string:\n\n```elixir\n# let's decode some of our earlier strings\nCID.decode(\"zadi4ekZWb9uwiPgSM1Fki5UAfvggkGC27Qy6acaYZ49jycsv\")\n# notice we also get the Multibase used\n{:ok,\n {%CID{\n    codec: \"cbor\",\n    multihash: \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92,\n      130, 235, 240, 88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167,\n      153, 175, 31, 65, 149\u003e\u003e,\n    version: 1\n  }, :base58_btc}}\n\n# we have our exception raising version again\nCID.decode!(\"zadi4ekZWb9uwiPgSM1Fki5UAfvggkGC27Qy6acaYZ49jycsv\")\n{%CID{\n   codec: \"cbor\",\n   multihash: \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92,\n     130, 235, 240, 88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153,\n     175, 31, 65, 149\u003e\u003e,\n   version: 1\n }, :base58_btc}\n\n# we can also get only the CID, exception raising version available\nCID.decode_cid!(\"mAXASIJW4gxsH5vZxGi3rXILr8Fhj0K2zMchrK63Ip5mvH0GV\") \n%CID{\ncodec: \"dag-pb\",\nmultihash: \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92,\n 130, 235, 240, 88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153,\n 175, 31, 65, 149\u003e\u003e,\nversion: 1\n}\n\n# fortunately our error handling versions have some sanity checks too\nCID.decode_cid(\"Why would a company named Franco American make Italian food?\")\n{:error, \"unable to decode CID string\"}\n\n# let's tamper with a string by adding \"Q\" to prove it\nCID.decode(\"QmAXASIJW4gxsH5vZxGi3rXILr8Fhj0K2zMchrK63Ip5mvH0GV\")\n{:error, \"unable to decode CID string\"}\n```\n\n## Human Readable CID Strings\n\nSometimes we want to better understand exactly *what* is in our CID. Fortunately, we can humanize a CID string like so:\n\n```elixir\n\n# help me make sense of all this\nCID.humanize(\"zadi4ekZWb9uwiPgSM1Fki5UAfvggkGC27Qy6acaYZ49jycsv\")          \n{:ok,\n \"base58_btc - CIDv1 - cbor - sha2_256 - 95b8831b07e6f6711a2deb5c82ebf05863d0adb331c86b2badc8a799af1f4195\"}\n\n# a custom separator\nCID.humanize(\"z4EBG9jACDDa7TeGCBUUk4ziuRsGmGnjefMx5GEofptsFxTaH8Q\", \":\")\n{:ok,\n \"base58_btc:CIDv1:dag-json:sha2_256:95b8831b07e6f6711a2deb5c82ebf05863d0adb331c86b2badc8a799af1f4195\"}\n\n# we can get sassy too with our own custom separators\nCID.humanize(\"QmYR6e57B15cM77ankTPqxsQVbFVzcYSGrFGr5WtmR8jdn\", \"\\_(ツ)_/¯\")\n{:ok,\n \"base58_btc_(ツ)_/¯CIDv0_(ツ)_/¯dag-pb_(ツ)_/¯sha2_256_(ツ)_/¯95b8831b07e6f6711a2deb5c82ebf05863d0adb331c86b2badc8a799af1f\"}\n```\n\n### CID Validity\n\nWhat if want to know whether or not a CID is valid? No problem:\n\n```elixir\n# vindication\nCID.cid?(\"z4EBG9jACDDa7TeGCBUUk4ziuRsGmGnjefMx5GEofptsFxTaH8Q\")\ntrue\n\n# sadly, not a valid ID\nCID.cid?(\"I want to persuade you that I am an ID\")\nfalse\n```\n\n### Convert a CID\n\nIf we have some need to convert CID representations, we can do it. This is more useful in the long-term. A typical use-case is to convert a CID v0 to a CID v1.\n\nThe simplest route would just be to decode and re-encode, however if we are still working with our struct or if we already decoded it, we have a simple option:\n\n```elixir\nCID.cid!(multihash, \"dag-pb\", 0) |\u003e CID.to_version(1)\n{:ok,\n %CID{\n   codec: \"dag-pb\",\n   multihash: \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92,\n     130, 235, 240, 88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153,\n     175, 31, 65, 149\u003e\u003e,\n   version: 1\n }}\n \n# we can't convert if we break the rules though of a version, such as CID v1 -\u003e CID v0\nCID.cid!(multihash, \"dag-cbor\", 1) |\u003e CID.to_version(0)\n{:error, :unsupported_conversion}\n\n# we can convert from CID v1 to CID v0 though if we follow the rules\nCID.cid!(v0_multihash, \"dag-pb\", 1) |\u003e CID.to_version(0)  \n# notice it works because the codec was \"dag-pb\"\n{:ok,\n %CID{\n   codec: \"dag-pb\",\n   multihash: \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92,\n     130, 235, 240, 88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153,\n     175, 31, 65, 149\u003e\u003e,\n   version: 0\n }}\n```\n\n### Summary - Encode and Decode Round-Trip\n\nFinally, to review let's round trip some data:\n\n```elixir\n# take a CID v1, encode it, then decode it back again\nCID.cid!(multihash, \"dag-pb\", 1) |\u003e CID.encode!() |\u003e CID.decode!()\n{%CID{\n   codec: \"dag-pb\",\n   multihash: \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92,\n     130, 235, 240, 88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153,\n     175, 31, 65, 149\u003e\u003e,\n   version: 1\n }, :base58_btc}\n\n# changing the default encoding while round tripping\nCID.cid!(multihash, \"cbor\") |\u003e CID.encode!(:base32_z) |\u003e CID.decode!()\n{%CID{\n   codec: \"cbor\",\n   multihash: \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92,\n     130, 235, 240, 88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153,\n     175, 31, 65, 149\u003e\u003e,\n   version: 1\n }, :base32_z}\n\n# round-tripping a v0 CID with some options \n CID.cid!(v0_multihash, \"dag-pb\", 0) |\u003e CID.encode!() |\u003e CID.decode_cid!()\n %CID{\n   codec: \"dag-pb\",\n   multihash: \u003c\u003c18, 32, 149, 184, 131, 27, 7, 230, 246, 113, 26, 45, 235, 92,\n     130, 235, 240, 88, 99, 208, 173, 179, 49, 200, 107, 43, 173, 200, 167, 153,\n     175, 31, 65, 149\u003e\u003e,\n   version: 0\n }\n```\n\n## Installation\n\nAvailable in [Hex](https://hex.pm/packages/cid). The package can be installed by adding `cid` to your list of dependencies in mix.exs:\n\n```elixir\ndef deps do\n  [\n    {:cid, \"~\u003e 0.0.1\"}\n  ]\nend\n```\n\nAPI Documentation can be found at [https://hexdocs.pm/cid](https://hexdocs.pm/cid).\n\n## Issues\n\nIn general, most questions are best answered via the [official CID project](https://github.com/ipld/cid) and by its members.\n\nIf you have Elixir specific issues, please open an issue here. Do not open Multibase, Multicodec, Multihash, or generic CID issues here.\n\nYou can also check the FAQ in the `docs` folder.\n\n## Acknowledgments\n\n* Motivation sections and other minor docs from [official CID project](https://github.com/ipld/cid)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnocursor%2Fex-cid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnocursor%2Fex-cid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnocursor%2Fex-cid/lists"}