# CID
An Elixir implementation of [Content Identifiers (CIDs)](https://github.com/multiformats/cid) — 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
```elixir
# 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
```elixir
# 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:
```elixir
{:ok, cid, rest} = CID.from_bytes(binary_data)
```
### Verifying content
Check that content matches a CID's hash:
```elixir
cid = CID.create("hello world")
CID.verify(cid, "hello world") # => :ok
CID.verify(cid, "wrong content") # => :mismatch
```
### Converting between representations
```elixir
# 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
```elixir
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
```elixir
%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:
- [multicodec](https://github.com/tyler-eon/multicodec) — codec identification and the central multiformats registry
- [multibase](https://github.com/tyler-eon/multibase) — base encoding/decoding
- [multihash](https://github.com/tyler-eon/multihash) — hash algorithm identification and digest wrapping
## Part of the multiformats ecosystem
For runtime codec registration and cross-component composition, see the [multicodec](https://github.com/tyler-eon/multicodec) project.