CID

An Elixir implementation of Content Identifiers (CIDs) — self-describing, content-addressed identifiers used throughout the IPFS and IPLD ecosystems.

A CID bundles together a version indicator, a content type codec, and a multihash of the content into a single identifier. Given a CID and the original content, anyone can verify that the content matches the identifier.

CID Versions

CIDv0 is the legacy format: a bare base58btc-encoded SHA-256 multihash, always 46 characters starting with "Qm". Content type is implicitly dag-pb.

CIDv1 is the self-describing format: a multibase-encoded binary containing the version varint, content codec varint, and multihash. The multibase prefix character identifies the string encoding.

Usage

Creating CIDs

# CIDv1 with defaults (raw content type, sha2-256, base32)
cid = CID.create("hello world")
cid.cid_string
# => "bafkreifzjut3te2nhyekklss27nh3k72ysco7y32koao5eei66wof36n5e"

# CIDv1 with custom options
cid = CID.create("hello world",
  content_type: "dag-cbor",
  hash_algorithm: "sha3-256",
  base: :base58btc
)

# CIDv0
cid = CID.create_v0("hello world")
cid.cid_string
# => "QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpu5rmrkPdT3L4"

Parsing CIDs

# Parse any CID string (v0 or v1, any multibase)
{:ok, cid} = CID.parse("bafkreifzjut3te2nhyekklss27nh3k72ysco7y32koao5eei66wof36n5e")
cid.version        # => 1
cid.content_type   # => "raw"
cid.hash_algorithm # => "sha2-256"
cid.hash_digest    # => <<185, 77, 39, ...>>

# Raising variant
cid = CID.parse!("QmaozNR7DZHQK1ZcU9p7QdrshMvXqWK6gpu5rmrkPdT3L4")
cid.version        # => 0

Parsing CIDs from raw bytes

For binary formats like CAR files, parse a CID from raw bytes and get back the remaining data:

{:ok, cid, rest} = CID.from_bytes(binary_data)

Verifying content

Check that content matches a CID's hash:

cid = CID.create("hello world")
CID.verify(cid, "hello world")    # => :ok
CID.verify(cid, "wrong content")  # => :mismatch

Converting between representations

# Struct to string
CID.cid_string(cid)
"#{cid}"  # String.Chars protocol is implemented

# Struct to raw bytes (no multibase encoding)
CID.to_bytes(cid)

Introspection

CID.valid?("bafkreifzjut3te...")  # => true
CID.valid?("not a cid")          # => false

CID.is_v0?(cid)  # works on structs and strings
CID.is_v1?(cid)
CID.v0?("QmaozN...")  # string-only check

The CID struct

%CID{
  version: 0 | 1,
  content_type: "raw" | "dag-cbor" | "dag-pb" | ...,
  hash_algorithm: "sha2-256" | "sha3-256" | ...,
  hash_size: 32,
  hash_digest: <<...>>,       # raw hash bytes
  multihash: <<...>>,         # codec-prefixed hash with length
  cid_bytes: <<...>>,         # full CID binary (no multibase)
  cid_string: "bafkrei..."   # multibase-encoded string
}

Dependencies

This library builds on top of three sibling multiformats libraries:

Part of the multiformats ecosystem

For runtime codec registration and cross-component composition, see the multicodec project.