package checkseum

  1. Overview
  2. Docs
Adler-32, CRC32 and CRC32-C implementation in C and OCaml


Dune Dependency






Checkseum is a library to provide implementation of Adler-32, CRC32 and CRC32-C in C and OCaml.

This library use the linking trick to choose between the C implementation (checkseum.c) or the OCaml implementation (checkseum.ocaml). This library is on top of optint to get the best representation of an int32.

Published: 18 Sep 2023



Chekseum is a library which implements ADLER-32 and CRC32C Cyclic Redundancy Check. It provides 2 implementation, the first in C and the second in OCaml. The library is on top of optint to get the best representation of the CRC in the OCaml world.

Linking trick / variant

Then, as digestif, checkseum uses the linking trick. So if you want to use checkseum in a library, you can link with the checkseum package which does not provide an implementation. Then, end-user can choose between the C implementation or the OCaml implementation (both work on Mirage).

So, in utop, to be able to fully use checkseum, you need to write:

$ utop -require checkseum.c


$ utop -require checkseum.ocaml

In a dune workspace, the build-system is able to choose silently default implementation (checkseum.c) for your executable if you don't specify one of them. A dune-library is not able to choose an implementatio but still able to use the virtual library checkseum.

The trick permits us to compile checkseum with js_of_ocaml.

Compatibility with 32-bits architecture

checkseum was made to provide a Adler-32 or a CRC-32 implementation regardless the architecture - it takes the advantage of optint to get in any situation a 32-bits integer. However, it takes the advantage of the immediate int value for a 64-bits architecture (which let us to use, at most, 63 bits).

The C implementation provides the cheapest FFI between OCaml and C via annotations such as [@untagged] or [@unboxed].


This is a simple example of how to use checkseum with CRC-32:

$ cat > <<EOF
let digest ic =
  let tmp = Bytes.create 0x1000 in
  let rec go crc32 = match input ic tmp 0 0x1000 with
    | 0 -> crc32
    | len ->
      Checkseum.Crc32.digest_bytes tmp 0 len crc32 |> go
    | exception End_of_file -> crc32 in
  go Checkseum.Crc32.default

let () = match Sys.argv with
  | [| _; filename |] when Sys.file_exists filename ->
    let ic = open_in filename in
    let crc32 = digest ic in
    close_in ic ; Format.printf "%a\n%!" Checkseum.Crc32.pp crc32
  | [| _ |] ->
    let crc32 = digest stdin in
    Format.printf "%a\n%!" Checkseum.Crc32.pp crc32
  | _ -> Format.eprintf "%s [<filename>]\n%!" Sys.argv.(0)
$ cat >dune <<EOF
 (name digest)
 (libraries checkseum))
$ dune exec ./digest.exe --


With the dune's profile benchmark (which requires bechamel), the user is able to produce a bench/main.html which compares checkseum.c with tcpip.

Dependencies (4)

  1. optint >= "0.3.0"
  2. dune-configurator
  3. dune >= "2.6.0"
  4. ocaml >= "4.07.0"

Dev Dependencies (7)

  1. ocamlfind with-test
  2. rresult with-test
  3. fpath with-test
  4. fmt with-test
  5. astring with-test
  6. bos with-test
  7. alcotest with-test

Conflicts (2)

  1. ocaml-freestanding
  2. mirage-xen < "6.0.0"