mfmts-1.2.0.0: README.md
mfmts [](
https://hackage.haskell.org/package/mfmts)[](
https://builds.sr.ht/~z0/mfmts/commits/main/ipfshs-ci.yml?)
---------------------------------------------------------------
This project implements the specifications described by Protocol Lab's
[multiformats](https://github.com/multiformats/multiformats) written in Haskell.
`cid` - Content identitiers for hashed data
-------------------------------------------
Provides functionality for the multiformats CID binary format. These modules
provide parsing CIDs from multibase prefixed digit strings, extracting CID data
from byte strings and serializing CIDs stored in memory into its binary format.
CID GitHub README example in GHCI:
```haskell
λ> {-# LANGUAGE OverloadedStrings #-}
λ> import MultiFormats.CID (CID)
λ> import MultiFormats.CID.Parser qualified as CID
λ> import MultiFormats.CID.Errors qualified as CID
λ> CID.parser "zb2rhe5P4gXftAwvA4eXQ5HJwsER2owDyS9sKaQRRVQPn93bA" :: CID.Okay CID
Right CIDv1(DataCodec=MultiCodec(raw=0x55), HashCodec=MultiHash(sha2-256=0x12), HashDigest[32]=0x6e6ff7950a36187a801613426e858dce686cd7d7e3c0fc42ee0330072d245c95)
```
- CID specification - [https://github.com/multiformats/cid](
https://github.com/multiformats/cid)
- CID example from README - [
https://github.com/multiformats/cid#variant---human-readable-form](
https://github.com/multiformats/cid#variant---human-readable-form)
- Official IPFS Golang implementation - [https://github.com/ipfs/go-cid](
https://github.com/ipfs/go-cid)
`multibase` - Multibase prefix data transcoding
-----------------------------------------------
Implements encoders and decoders for numeric basesystems identified by a
specified prefix symbol. It implements transcoders from the [basesystems](
https://git.sr.ht/~z0/basesystems) library, allowing for different types of
bytestring data to be specified as type parameters.
Multibase GitHub README example in GHCI:
```haskell
λ> {-# LANGUAGE OverloadedStrings #-}
λ> import MultiFormats.MultiBase.DigitTranscoder (decodeFromPrefix)
λ> import Data.ByteString.Short (ShortByteString)
λ> import Data.ByteString.Lazy (LazyByteString)
λ> type Sbs = ShortByteString
λ> type Lbs = LazyByteString
λ> -- uppercase hexadecimal (F)
λ> decodeFromPrefix "F4D756C74696261736520697320617765736F6D6521205C6F2F" :: Maybe Sbs
Just "Multibase is awesome! \\o/"
λ> -- base32 no padding (B)
λ> decodeFromPrefix "BJV2WY5DJMJQXGZJANFZSAYLXMVZW63LFEEQFY3ZP" :: Maybe Lbs
Just "Multibase is awesome! \\o/"
λ> -- bitcoin base58 (z)
λ> decodeFromPrefix "zYAjKoNbau5KiqmHPmSxYCvn66dA1vLmwbt" :: Maybe Sbs
Just "Multibase is awesome! \\o/"
λ> -- base64 with padding (M)
λ> decodeFromPrefix "MTXVsdGliYXNlIGlzIGF3ZXNvbWUhIFxvLw==" :: Maybe Lbs
Just "Multibase is awesome! \\o/"
```
- Multibase specification - [https://github.com/multiformats/multibase](
https://github.com/multiformats/multibase)
- Multibase example - [
https://github.com/multiformats/multibase#multibase-by-example](
https://github.com/multiformats/multibase#multibase-by-example)
`multicodec` - Magic number specifications
------------------------------------------
Provides lookup table and query functions for codecs defined from multiformats
multicodec. These are magic numbers that represent certain data encoded within
CIDs, mulithash and other related projects. This module has code which
is generated by a python script in the [ipfshs](https://todo.sr.ht/~z0/ipfshs)
repo, and is automatically generated from CSV.
Example of looking up codecs:
```haskell
λ> import MultiFormats.MultiCodec qualified as MC
λ> -- Resolving from codec values:
λ> MC.resolveCodecName $ MC.MultiCodec 0x1
Just "cidv1"
λ> -- Resolving from names:
λ> MC.resolveCodecValue "cidv1"
Just MultiCodec(0x1, "cidv1")
λ> MC.resolveCodecValue "cidv0"
Nothing
```
- Multicodec specification - [https://github.com/multiformats/multicodec](
https://github.com/multiformats/multicodec)
- Multicodec value table - [
https://github.com/multiformats/multicodec/blob/master/table.csv](
https://github.com/multiformats/multicodec/blob/master/table.csv)
`multihash` - Multicodec hash function identifiers
--------------------------------------------------
Multihashes are a type of multicodec for identifying hash functions. This
code provides a lookup table for hash functions from the multicodec module, and
a way to get hash digests from specific functions over bytestrings, and to
verify multicodec values as valid multihash codecs.
Example of looking up hash functions and applying them:
```haskell
λ> import MultiFormats.MultiCodec qualified as MC
λ> import MultiFormats.MultiHash qualified as MH
λ> -- Here's an example of how we can verify names and codec values as valid
λ> -- hash functions.
λ> MH.resolveHashCodec $ MC.MultiCodec 0x12
Just MultiHash(0x12, "sha2-256")
λ> MH.resolveHashName "sha2-256"
Just MultiHash(0x12, "sha2-256")
λ> -- Building a function call that hashes the string "Hello World!" using the
λ> -- sha2-256 algorithm, then outputs the digest as hexadecimal:
λ> import Data.BaseSystem.Lazy (encoder, base16lower)
λ> import Data.ByteString.Builder qualified as Builder
λ> import Data.Maybe (fromJust)
λ> let sha256 = MH.multiHashFunction $ fromJust (MH.resolveHashName "sha2-256")
λ> let input = Builder.string8 "Hello World!"
λ> encoder base16lower $ sha256 input
"7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069"
```
- Multihash specification - [https://github.com/multiformats/multihash](
https://github.com/multiformats/multihash)
- Multiformat's Golang implementation - [
https://github.com/multiformats/go-multihash](
https://github.com/multiformats/go-multihash)
`varint` - Unsigned variable length integers
--------------------------------------------
Provides parsing and serialization for multiformats unsigned binary varints,
with the special caveat from multiformats that requires them always to be
minimally encoded, so this project also verifies that the varint inputs comply
with the rules of the multiformats specification.
Varint GitHub README example in GHCI using `packValue` from the [basesystems](
https://git.sr.ht/~z0/basesystems) library to transfer constants into
bytestrings. We can then use `extractVarInt` to get the varint representation
from the bytes:
```haskell
λ> import Data.BaseSystem.BinaryTranscoder (packValue)
λ> import Data.ByteString.Short (ShortByteString)
λ> import MultiFormats.VarInt (VarInt, extractVarInt)
λ> import MultiFormats.VarInt.Errors qualified as VarInt
λ> -- Make alias so we don't get type warnings
λ> let packInteger x = packValue (x :: Integer)
λ> -- 7-bit values fit into 1 byte:
λ> extractVarInt (packInteger 0x01) :: VarInt.Okay (VarInt, ShortByteString)
Right (1,"")
λ> extractVarInt (packInteger 0x7f) :: VarInt.Okay (VarInt, ShortByteString)
Right (127,"")
λ> -- 8-bit and larger values have their MSB set until a zero MSB byte is found:
λ> extractVarInt (packInteger 0x8001) :: VarInt.Okay (VarInt, ShortByteString)
Right (128,"")
λ> extractVarInt (packInteger 0xff01) :: VarInt.Okay (VarInt, ShortByteString)
Right (255,"")
λ> extractVarInt (packInteger 0xac02) :: VarInt.Okay (VarInt, ShortByteString)
Right (300,"")
λ> extractVarInt (packInteger 0x808001) :: VarInt.Okay (VarInt, ShortByteString)
Right (16384,"")
```
- Varint specification - [https://github.com/multiformats/unsigned-varint](
https://github.com/multiformats/unsigned-varint)
Development
-----------
Unit tests are provided on the main [ipfshs repo](https://git.sr.ht/~z0/ipfshs),
and bugs can be reported on [ipfshs ticket tracker](
https://todo.sr.ht/~z0/ipfshs).
Licensing
---------
The `mfmts` project and its modules are free software and licensed under the
[AGPLv3](https://www.gnu.org/licenses/agpl-3.0.en.html) license. See
[LICENSE.txt](LICENSE.txt).
Copyright © 2026 Zoey McBride | [zoeymcbride@mailbox.org](
mailto:zoeymcbride@mailbox.org)