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.

CRC-32: use Int32 via C32 module for js_of_ocaml compatibility

Remove assert (Sys.int_size > 32) that crashes on 32-bit targets.
CRC-32 and CRC-32C now use a C32 submodule with Int32 arithmetic,
correct on both 64-bit native and js_of_ocaml. CRC-16 unchanged.

+45 -45
+45 -45
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 (* {1 CRC-16-CCITT} 5 2 6 3 Polynomial: x^16 + x^12 + x^5 + 1 (0x1021) ··· 53 50 done; 54 51 !crc lxor 0xFFFF 55 52 56 - (* {1 CRC-32 (ISO 3309)} 53 + (* {1 CRC-32} 54 + 55 + All CRC-32 variants use Int32 arithmetic so they work on both 56 + 64-bit native OCaml and 32-bit targets (js_of_ocaml, wasm). *) 57 + 58 + module C32 = struct 59 + let ( lxor ) = Int32.logxor 60 + let ( land ) = Int32.logand 61 + let ( lsr ) = Int32.shift_right_logical 62 + 63 + let make_table poly = 64 + Array.init 256 (fun i -> 65 + let crc = ref (Int32.of_int i) in 66 + for _ = 0 to 7 do 67 + if !crc land 1l <> 0l then crc := (!crc lsr 1) lxor poly 68 + else crc := !crc lsr 1 69 + done; 70 + !crc) 71 + 72 + let compute table data = 73 + let crc = ref 0xFFFFFFFFl in 74 + for i = 0 to String.length data - 1 do 75 + let byte = Int32.of_int (Char.code (String.unsafe_get data i)) in 76 + let idx = Int32.to_int ((!crc lxor byte) land 0xFFl) in 77 + crc := table.(idx) lxor (!crc lsr 8) 78 + done; 79 + Int32.to_int (!crc lxor 0xFFFFFFFFl) 80 + 81 + let compute_bytes table buf off len = 82 + let crc = ref 0xFFFFFFFFl in 83 + for i = off to off + len - 1 do 84 + let byte = Int32.of_int (Char.code (Bytes.unsafe_get buf i)) in 85 + let idx = Int32.to_int ((!crc lxor byte) land 0xFFl) in 86 + crc := table.(idx) lxor (!crc lsr 8) 87 + done; 88 + Int32.to_int (!crc lxor 0xFFFFFFFFl) 89 + end 90 + 91 + (* {2 CRC-32 (ISO 3309)} 57 92 58 93 Polynomial: 0xEDB88320 (reflected form of 0x04C11DB7) 59 94 Init: 0xFFFFFFFF, XOR out: 0xFFFFFFFF. *) 60 95 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) 96 + let crc32_table = C32.make_table 0xEDB88320l 97 + let crc32 data = C32.compute crc32_table data 69 98 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)} 99 + (* {2 CRC-32C (Castagnoli)} 79 100 80 101 Polynomial: 0x82F63B78 (reflected form of 0x1EDC6F41) 81 102 Init: 0xFFFFFFFF, XOR out: 0xFFFFFFFF. 82 103 Used by iSCSI, ext4, Btrfs. *) 83 104 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 105 + let crc32c_table = C32.make_table 0x82F63B78l 106 + let crc32c data = C32.compute crc32c_table data 107 + let crc32c_bytes buf off len = C32.compute_bytes crc32c_table buf off len