CRC checksums (CRC-16, CRC-32, CRC-32C) for OCaml
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(crc): add ocaml-crc package with CRC-16/32/32C implementations

Pure OCaml table-based CRC checksums: CRC-16-CCITT (ITU-T V.41),
CRC-16-X.25, CRC-32 (ISO 3309), and CRC-32C (Castagnoli/RFC 3720).
All functions return native int (no Int32 boxing). Requires 64-bit OCaml.

Includes Alcotest vectors from ITU-T V.41, ISO 3309, RFC 3720 Section 12.1,
and Crowbar fuzz tests for string/bytes agreement, self-check residue,
range bounds, and determinism.

+486
+5
.gitignore
··· 1 + _build/ 2 + *.install 3 + .merlin 4 + *.opam.locked 5 + _opam/
+1
.ocamlformat
··· 1 + version = 0.28.1
+13
LICENSE.md
··· 1 + Copyright (c) 2025 Thomas Gazagnaire <thomas@gazagnaire.org> 2 + 3 + Permission to use, copy, modify, and distribute this software for any 4 + purpose with or without fee is hereby granted, provided that the above 5 + copyright notice and this permission notice appear in all copies. 6 + 7 + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+46
README.md
··· 1 + # ocaml-crc — CRC checksums for OCaml 2 + 3 + Pure OCaml table-based implementations of common CRC algorithms. 4 + 5 + ## Algorithms 6 + 7 + | Algorithm | Polynomial | Init | Reflect | XOR Out | Check (`"123456789"`) | Standard | 8 + |-----------|-----------|------|---------|---------|----------------------|----------| 9 + | CRC-16-CCITT | 0x1021 | 0xFFFF | No | None | 0x29B1 | ITU-T V.41, CCSDS FECF | 10 + | CRC-16-X.25 | 0x1021 | 0xFFFF | Yes | 0xFFFF | 0x906E | ITU-T X.25, RFC 9171 | 11 + | CRC-32 | 0xEDB88320 | 0xFFFFFFFF | Yes | 0xFFFFFFFF | 0xCBF43926 | ISO 3309, ITU-T V.42 | 12 + | CRC-32C | 0x82F63B78 | 0xFFFFFFFF | Yes | 0xFFFFFFFF | 0xE3069283 | RFC 3720 (iSCSI) | 13 + 14 + ## Usage 15 + 16 + ```ocaml 17 + let () = 18 + let data = "Hello, world!" in 19 + Printf.printf "CRC-16-CCITT: 0x%04X\n" (Crc.crc16_ccitt data); 20 + Printf.printf "CRC-16-X.25: 0x%04X\n" (Crc.crc16_x25 data); 21 + Printf.printf "CRC-32: 0x%08X\n" (Crc.crc32 data); 22 + Printf.printf "CRC-32C: 0x%08X\n" (Crc.crc32c data) 23 + ``` 24 + 25 + Sub-range variants for bytes buffers: 26 + 27 + ```ocaml 28 + let buf = Bytes.of_string "Hello, world!" in 29 + let crc16 = Crc.crc16_ccitt_bytes buf 0 5 in (* CRC of "Hello" *) 30 + let crc32c = Crc.crc32c_bytes buf 7 6 in (* CRC of "world!" *) 31 + ``` 32 + 33 + ## Install 34 + 35 + ``` 36 + opam install crc 37 + ``` 38 + 39 + ## Test vectors 40 + 41 + All check values are verified against Python's `crcmod` library and 42 + standard test vectors from ITU-T V.41, ISO 3309, and RFC 3720 Section 12.1. 43 + 44 + ## License 45 + 46 + ISC
+30
crc.opam
··· 1 + # This file is generated by dune, edit dune-project instead 2 + opam-version: "2.0" 3 + synopsis: "CRC checksums for OCaml" 4 + description: 5 + "Pure OCaml implementations of common CRC algorithms: CRC-16-CCITT, CRC-16-X.25, CRC-32, and CRC-32C (Castagnoli). Table-based for performance." 6 + maintainer: ["Thomas Gazagnaire <thomas@gazagnaire.org>"] 7 + authors: ["Thomas Gazagnaire <thomas@gazagnaire.org>"] 8 + license: "ISC" 9 + depends: [ 10 + "dune" {>= "3.21"} 11 + "ocaml" {>= "4.14"} 12 + "alcotest" {with-test} 13 + "crowbar" {with-test} 14 + "odoc" {with-doc} 15 + ] 16 + build: [ 17 + ["dune" "subst"] {dev} 18 + [ 19 + "dune" 20 + "build" 21 + "-p" 22 + name 23 + "-j" 24 + jobs 25 + "@install" 26 + "@runtest" {with-test} 27 + "@doc" {with-doc} 28 + ] 29 + ] 30 + x-maintenance-intent: ["(latest)"]
+21
dune-project
··· 1 + (lang dune 3.21) 2 + 3 + (name crc) 4 + 5 + (generate_opam_files true) 6 + 7 + (license ISC) 8 + (authors "Thomas Gazagnaire <thomas@gazagnaire.org>") 9 + (maintainers "Thomas Gazagnaire <thomas@gazagnaire.org>") 10 + 11 + (package 12 + (name crc) 13 + (synopsis "CRC checksums for OCaml") 14 + (description 15 + "Pure OCaml implementations of common CRC algorithms: CRC-16-CCITT, \ 16 + CRC-16-X.25, CRC-32, and CRC-32C (Castagnoli). Table-based for \ 17 + performance.") 18 + (depends 19 + (ocaml (>= 4.14)) 20 + (alcotest :with-test) 21 + (crowbar :with-test)))
+3
fuzz/dune
··· 1 + (test 2 + (name fuzz_crc) 3 + (libraries crc crowbar))
+67
fuzz/fuzz_crc.ml
··· 1 + (* Fuzz tests for CRC functions. 2 + 3 + Properties tested: 4 + - CRC-16-CCITT: string vs bytes agree, self-check residue is 0 5 + - CRC-16-X.25: output in 16-bit range 6 + - CRC-32C: string vs bytes agree 7 + - All: deterministic (same input → same output) *) 8 + 9 + let () = 10 + (* CRC-16-CCITT: string and bytes sub-range agree *) 11 + Crowbar.add_test ~name:"crc16_ccitt: string = bytes" [ Crowbar.bytes ] 12 + (fun s -> 13 + let from_string = Crc.crc16_ccitt s in 14 + let from_bytes = 15 + Crc.crc16_ccitt_bytes (Bytes.of_string s) 0 (String.length s) 16 + in 17 + Crowbar.check_eq ~pp:Format.pp_print_int from_string from_bytes); 18 + 19 + (* CRC-16-CCITT: self-check property — CRC(msg || CRC_BE) = 0 *) 20 + Crowbar.add_test ~name:"crc16_ccitt: self-check residue" [ Crowbar.bytes ] 21 + (fun s -> 22 + let crc = Crc.crc16_ccitt s in 23 + let with_crc = 24 + s 25 + ^ String.init 2 (fun i -> 26 + Char.chr (if i = 0 then (crc lsr 8) land 0xFF else crc land 0xFF)) 27 + in 28 + let residue = Crc.crc16_ccitt with_crc in 29 + Crowbar.check_eq ~pp:Format.pp_print_int 0 residue); 30 + 31 + (* CRC-16-CCITT: output is 16-bit *) 32 + Crowbar.add_test ~name:"crc16_ccitt: 16-bit range" [ Crowbar.bytes ] (fun s -> 33 + let crc = Crc.crc16_ccitt s in 34 + Crowbar.check (crc >= 0 && crc <= 0xFFFF)); 35 + 36 + (* CRC-16-X.25: output is 16-bit *) 37 + Crowbar.add_test ~name:"crc16_x25: 16-bit range" [ Crowbar.bytes ] (fun s -> 38 + let crc = Crc.crc16_x25 s in 39 + Crowbar.check (crc >= 0 && crc <= 0xFFFF)); 40 + 41 + (* CRC-32: output is non-negative *) 42 + Crowbar.add_test ~name:"crc32: non-negative" [ Crowbar.bytes ] (fun s -> 43 + let crc = Crc.crc32 s in 44 + Crowbar.check (crc >= 0)); 45 + 46 + (* CRC-32C: string and bytes sub-range agree *) 47 + Crowbar.add_test ~name:"crc32c: string = bytes" [ Crowbar.bytes ] (fun s -> 48 + let from_string = Crc.crc32c s in 49 + let from_bytes = 50 + Crc.crc32c_bytes (Bytes.of_string s) 0 (String.length s) 51 + in 52 + Crowbar.check_eq ~pp:Format.pp_print_int from_string from_bytes); 53 + 54 + (* CRC-32C: output is 32-bit *) 55 + Crowbar.add_test ~name:"crc32c: 32-bit range" [ Crowbar.bytes ] (fun s -> 56 + let crc = Crc.crc32c s in 57 + Crowbar.check (crc >= 0 && crc <= 0xFFFFFFFF)); 58 + 59 + (* CRC-16-CCITT: deterministic *) 60 + Crowbar.add_test ~name:"crc16_ccitt: deterministic" [ Crowbar.bytes ] 61 + (fun s -> 62 + Crowbar.check_eq ~pp:Format.pp_print_int (Crc.crc16_ccitt s) 63 + (Crc.crc16_ccitt s)); 64 + 65 + (* CRC-32C: deterministic *) 66 + Crowbar.add_test ~name:"crc32c: deterministic" [ Crowbar.bytes ] (fun s -> 67 + Crowbar.check_eq ~pp:Format.pp_print_int (Crc.crc32c s) (Crc.crc32c s))
+107
lib/crc.ml
··· 1 + (* Requires 64-bit OCaml: CRC-32 polynomials need >32 bits of native int. *) 2 + let () = assert (Sys.int_size > 32) 3 + 4 + (* {1 CRC-16-CCITT} 5 + 6 + Polynomial: x^16 + x^12 + x^5 + 1 (0x1021) 7 + Init: 0xFFFF, no reflection, no final XOR. *) 8 + 9 + let crc16_ccitt_table = 10 + Array.init 256 (fun i -> 11 + let crc = ref (i lsl 8) in 12 + for _ = 0 to 7 do 13 + if !crc land 0x8000 <> 0 then 14 + crc := (!crc lsl 1) lxor 0x1021 land 0xFFFF 15 + else crc := (!crc lsl 1) land 0xFFFF 16 + done; 17 + !crc) 18 + 19 + let crc16_ccitt data = 20 + let crc = ref 0xFFFF in 21 + for i = 0 to String.length data - 1 do 22 + let byte = Char.code (String.unsafe_get data i) in 23 + let idx = (!crc lsr 8) lxor byte land 0xFF in 24 + crc := (!crc lsl 8) lxor crc16_ccitt_table.(idx) land 0xFFFF 25 + done; 26 + !crc 27 + 28 + let crc16_ccitt_bytes buf off len = 29 + let crc = ref 0xFFFF in 30 + for i = off to off + len - 1 do 31 + let byte = Char.code (Bytes.unsafe_get buf i) in 32 + let idx = (!crc lsr 8) lxor byte land 0xFF in 33 + crc := (!crc lsl 8) lxor crc16_ccitt_table.(idx) land 0xFFFF 34 + done; 35 + !crc 36 + 37 + (* {1 CRC-16-X.25} 38 + 39 + Polynomial: 0x8408 (reflected form of 0x1021) 40 + Init: 0xFFFF, reflected in/out, XOR out: 0xFFFF. 41 + Bit-at-a-time reflected algorithm (fast enough for small frames). *) 42 + 43 + let crc16_x25 data = 44 + let crc = ref 0xFFFF in 45 + for i = 0 to String.length data - 1 do 46 + let byte = Char.code (String.unsafe_get data i) in 47 + for j = 0 to 7 do 48 + let bit = (byte lsr j) land 1 in 49 + let c0 = !crc land 1 in 50 + crc := !crc lsr 1; 51 + if bit lxor c0 = 1 then crc := !crc lxor 0x8408 52 + done 53 + done; 54 + !crc lxor 0xFFFF 55 + 56 + (* {1 CRC-32 (ISO 3309)} 57 + 58 + Polynomial: 0xEDB88320 (reflected form of 0x04C11DB7) 59 + Init: 0xFFFFFFFF, XOR out: 0xFFFFFFFF. *) 60 + 61 + let crc32_table = 62 + Array.init 256 (fun i -> 63 + let crc = ref i in 64 + for _ = 0 to 7 do 65 + if !crc land 1 <> 0 then crc := (!crc lsr 1) lxor 0xEDB88320 66 + else crc := !crc lsr 1 67 + done; 68 + !crc) 69 + 70 + let crc32 data = 71 + let crc = ref 0xFFFFFFFF in 72 + for i = 0 to String.length data - 1 do 73 + let byte = Char.code (String.unsafe_get data i) in 74 + crc := crc32_table.(!crc lxor byte land 0xFF) lxor (!crc lsr 8) 75 + done; 76 + !crc lxor 0xFFFFFFFF 77 + 78 + (* {1 CRC-32C (Castagnoli)} 79 + 80 + Polynomial: 0x82F63B78 (reflected form of 0x1EDC6F41) 81 + Init: 0xFFFFFFFF, XOR out: 0xFFFFFFFF. 82 + Used by iSCSI, ext4, Btrfs. *) 83 + 84 + let crc32c_table = 85 + Array.init 256 (fun i -> 86 + let crc = ref i in 87 + for _ = 0 to 7 do 88 + if !crc land 1 <> 0 then crc := (!crc lsr 1) lxor 0x82F63B78 89 + else crc := !crc lsr 1 90 + done; 91 + !crc) 92 + 93 + let crc32c data = 94 + let crc = ref 0xFFFFFFFF in 95 + for i = 0 to String.length data - 1 do 96 + let byte = Char.code (String.unsafe_get data i) in 97 + crc := crc32c_table.(!crc lxor byte land 0xFF) lxor (!crc lsr 8) 98 + done; 99 + !crc lxor 0xFFFFFFFF 100 + 101 + let crc32c_bytes buf off len = 102 + let crc = ref 0xFFFFFFFF in 103 + for i = off to off + len - 1 do 104 + let byte = Char.code (Bytes.unsafe_get buf i) in 105 + crc := crc32c_table.(!crc lxor byte land 0xFF) lxor (!crc lsr 8) 106 + done; 107 + !crc lxor 0xFFFFFFFF
+34
lib/crc.mli
··· 1 + (** CRC checksums. 2 + 3 + Pure OCaml table-based implementations of common CRC algorithms. *) 4 + 5 + (** {1 CRC-16} *) 6 + 7 + val crc16_ccitt : string -> int 8 + (** [crc16_ccitt data] computes the CRC-16-CCITT checksum of [data]. Polynomial 9 + 0x1021, initial value 0xFFFF, no reflection. Used by CCSDS space protocols 10 + (AOS, TM, TC, USLP) as the Frame Error Control Field. *) 11 + 12 + val crc16_ccitt_bytes : bytes -> int -> int -> int 13 + (** [crc16_ccitt_bytes buf off len] computes CRC-16-CCITT over a sub-range of 14 + [buf]. *) 15 + 16 + val crc16_x25 : string -> int 17 + (** [crc16_x25 data] computes the CRC-16 X.25 checksum of [data]. Polynomial 18 + 0x1021, initial value 0xFFFF, reflected in/out, XOR out 0xFFFF. Used by 19 + ITU-T X.25, ISO/IEC 14443-3 (RFID), and Bundle Protocol (RFC 9171). *) 20 + 21 + (** {1 CRC-32} *) 22 + 23 + val crc32 : string -> int 24 + (** [crc32 data] computes the CRC-32 checksum of [data] (ISO 3309). Polynomial 25 + 0xEDB88320 (reflected), initial value 0xFFFFFFFF, XOR out 0xFFFFFFFF. 26 + Returns a non-negative integer on 64-bit platforms. *) 27 + 28 + val crc32c : string -> int 29 + (** [crc32c data] computes the CRC-32C (Castagnoli) checksum of [data]. 30 + Polynomial 0x82F63B78 (reflected). Used by iSCSI, ext4, Btrfs. Returns a 31 + non-negative integer on 64-bit platforms. *) 32 + 33 + val crc32c_bytes : bytes -> int -> int -> int 34 + (** [crc32c_bytes buf off len] computes CRC-32C over a sub-range of [buf]. *)
+3
lib/dune
··· 1 + (library 2 + (name crc) 3 + (public_name crc))
+3
test/dune
··· 1 + (test 2 + (name test) 3 + (libraries crc alcotest))
+1
test/test.ml
··· 1 + let () = Alcotest.run (fst Test_crc.suite) (snd Test_crc.suite)
+151
test/test_crc.ml
··· 1 + let check = Alcotest.(check int) 2 + 3 + (* ITU-T V.41 / CCITT standard check value: CRC of "123456789" = 0x29B1 4 + Reference: ITU-T Recommendation V.41, Annex I *) 5 + let check_string = "123456789" 6 + 7 + (* {1 CRC-16-CCITT (ITU-T V.41)} 8 + 9 + Polynomial: x^16 + x^12 + x^5 + 1 (0x1021) 10 + Init: 0xFFFF, no reflection, no final XOR. 11 + CCSDS 132.0-B-3 Section 4.1.4 (TM FECF), CCSDS 232.0-B-4 Section 4.1.4.1 12 + (TC FECF), CCSDS 732.0-B-4 Section 4.1.4 (AOS FECF). *) 13 + 14 + let test_crc16_ccitt_check () = 15 + check "ITU-T V.41 check value" 0x29B1 (Crc.crc16_ccitt check_string) 16 + 17 + let test_crc16_ccitt_empty () = 18 + (* Init value passes through unchanged for zero-length input *) 19 + check "empty input" 0xFFFF (Crc.crc16_ccitt "") 20 + 21 + let test_crc16_ccitt_bytes () = 22 + let buf = Bytes.of_string ("xxx" ^ check_string ^ "yyy") in 23 + check "bytes sub-range" 0x29B1 24 + (Crc.crc16_ccitt_bytes buf 3 (String.length check_string)) 25 + 26 + let test_crc16_ccitt_single () = 27 + check "single byte 0x41" 0xB915 (Crc.crc16_ccitt "A") 28 + 29 + (* CCSDS 732.0-B-4 Annex F.1: example AOS frame CRC. 30 + All-zeros payload should produce a well-defined CRC. *) 31 + let test_crc16_ccitt_zeros () = 32 + check "8 zero bytes" 0x313E (Crc.crc16_ccitt (String.make 8 '\x00')) 33 + 34 + (* Verify self-check property: CRC(data || CRC) = 0 for CCITT-FALSE variant. 35 + For init=0xFFFF no-reflect, appending the CRC big-endian yields residue 0. *) 36 + let test_crc16_ccitt_self_check () = 37 + let data = "Hello" in 38 + let crc = Crc.crc16_ccitt data in 39 + let with_crc = 40 + data 41 + ^ String.init 2 (fun i -> 42 + Char.chr (if i = 0 then (crc lsr 8) land 0xFF else crc land 0xFF)) 43 + in 44 + check "self-check residue" 0 (Crc.crc16_ccitt with_crc) 45 + 46 + (* {1 CRC-16-X.25} 47 + 48 + Polynomial: 0x1021, reflected in/out, init 0xFFFF, XOR out 0xFFFF. 49 + ITU-T X.25 Section 2.2.7.4, ISO/IEC 13239:2002 Section 4.2.5.2. 50 + Also used by Bundle Protocol (RFC 9171 Section 6.3). *) 51 + 52 + let test_crc16_x25_check () = 53 + check "ITU-T X.25 check value" 0x906E (Crc.crc16_x25 check_string) 54 + 55 + let test_crc16_x25_empty () = 56 + (* init 0xFFFF XOR out 0xFFFF = 0x0000 *) 57 + check "empty input" 0x0000 (Crc.crc16_x25 "") 58 + 59 + let test_crc16_x25_single () = 60 + check "single byte 0x41" 0xA3F5 (Crc.crc16_x25 "A") 61 + 62 + (* {1 CRC-32 (ISO 3309)} 63 + 64 + Polynomial: 0x04C11DB7 (reflected: 0xEDB88320) 65 + Init: 0xFFFFFFFF, XOR out: 0xFFFFFFFF. 66 + ISO 3309 Section 4.1, ITU-T V.42 Section 8.1.1.6.1. 67 + Also CCSDS 732.1-B-2 Section 4.1.4.2 (USLP CRC-32). *) 68 + 69 + let test_crc32_check () = 70 + check "ISO 3309 check value" 0xCBF43926 (Crc.crc32 check_string) 71 + 72 + let test_crc32_empty () = check "empty input" 0 (Crc.crc32 "") 73 + let test_crc32_single () = check "single byte 0x41" 0xD3D99E8B (Crc.crc32 "A") 74 + 75 + (* {1 CRC-32C (Castagnoli)} 76 + 77 + Polynomial: 0x1EDC6F41 (reflected: 0x82F63B78) 78 + Init: 0xFFFFFFFF, XOR out: 0xFFFFFFFF. 79 + RFC 3720 Section 12.1 (iSCSI), RFC 3385 (SCTP). 80 + Used by ext4, Btrfs, SpaceOS superblock validation. *) 81 + 82 + let test_crc32c_check () = 83 + (* RFC 3720 Section 12.1: CRC-32C("123456789") = 0xE3069283 *) 84 + check "RFC 3720 check value" 0xE3069283 (Crc.crc32c check_string) 85 + 86 + let test_crc32c_empty () = check "empty input" 0 (Crc.crc32c "") 87 + 88 + let test_crc32c_bytes () = 89 + let buf = Bytes.of_string ("xx" ^ check_string ^ "zz") in 90 + check "bytes sub-range" 0xE3069283 91 + (Crc.crc32c_bytes buf 2 (String.length check_string)) 92 + 93 + (* RFC 3720 Section 12.1 test vectors *) 94 + let test_crc32c_rfc3720_zeros () = 95 + (* 32 bytes of zeros *) 96 + let data = String.make 32 '\x00' in 97 + check "RFC 3720: 32 zeros" 0x8A9136AA (Crc.crc32c data) 98 + 99 + let test_crc32c_rfc3720_ff () = 100 + (* 32 bytes of 0xFF *) 101 + let data = String.make 32 '\xFF' in 102 + check "RFC 3720: 32x 0xFF" 0x62A8AB43 (Crc.crc32c data) 103 + 104 + let test_crc32c_rfc3720_ascending () = 105 + (* 32 bytes: 0x00, 0x01, ..., 0x1F *) 106 + let data = String.init 32 (fun i -> Char.chr i) in 107 + check "RFC 3720: ascending bytes" 0x46DD794E (Crc.crc32c data) 108 + 109 + let test_crc32c_rfc3720_descending () = 110 + (* 32 bytes: 0x1F, 0x1E, ..., 0x00 *) 111 + let data = String.init 32 (fun i -> Char.chr (31 - i)) in 112 + check "RFC 3720: descending bytes" 0x113FDB5C (Crc.crc32c data) 113 + 114 + let suite = 115 + ( "crc", 116 + [ 117 + ( "crc16-ccitt", 118 + [ 119 + Alcotest.test_case "ITU-T V.41 check" `Quick test_crc16_ccitt_check; 120 + Alcotest.test_case "empty" `Quick test_crc16_ccitt_empty; 121 + Alcotest.test_case "bytes sub-range" `Quick test_crc16_ccitt_bytes; 122 + Alcotest.test_case "single byte" `Quick test_crc16_ccitt_single; 123 + Alcotest.test_case "8 zero bytes" `Quick test_crc16_ccitt_zeros; 124 + Alcotest.test_case "self-check" `Quick test_crc16_ccitt_self_check; 125 + ] ); 126 + ( "crc16-x25", 127 + [ 128 + Alcotest.test_case "ITU-T X.25 check" `Quick test_crc16_x25_check; 129 + Alcotest.test_case "empty" `Quick test_crc16_x25_empty; 130 + Alcotest.test_case "single byte" `Quick test_crc16_x25_single; 131 + ] ); 132 + ( "crc32", 133 + [ 134 + Alcotest.test_case "ISO 3309 check" `Quick test_crc32_check; 135 + Alcotest.test_case "empty" `Quick test_crc32_empty; 136 + Alcotest.test_case "single byte" `Quick test_crc32_single; 137 + ] ); 138 + ( "crc32c", 139 + [ 140 + Alcotest.test_case "RFC 3720 check" `Quick test_crc32c_check; 141 + Alcotest.test_case "empty" `Quick test_crc32c_empty; 142 + Alcotest.test_case "bytes sub-range" `Quick test_crc32c_bytes; 143 + Alcotest.test_case "RFC 3720: 32 zeros" `Quick 144 + test_crc32c_rfc3720_zeros; 145 + Alcotest.test_case "RFC 3720: 32x 0xFF" `Quick test_crc32c_rfc3720_ff; 146 + Alcotest.test_case "RFC 3720: ascending" `Quick 147 + test_crc32c_rfc3720_ascending; 148 + Alcotest.test_case "RFC 3720: descending" `Quick 149 + test_crc32c_rfc3720_descending; 150 + ] ); 151 + ] )
+1
test/test_crc.mli
··· 1 + val suite : string * (string * unit Alcotest.test_case list) list