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.

Add mission-ready GMAT interop tests: 3 expected failures

Tests that expose real gaps in our libraries when compared against GMAT:

ocaml-odm (2 FAIL):
- LEO interpolation midpoint: linear vs quadratic truth returns inf —
exposes precision bug in interpolate epoch conversion
- Molniya perigee interpolation: same issue at high-eccentricity perigee

ocaml-collision (1 FAIL):
- TCA precision: miss distance varies by 34 km in 10s at closest approach.
Step-based TCA finding is not mission-grade — need quadratic refinement.

ocaml-cam (new mission-ready tests, passing):
- Linear model (dv*dt) vs GMAT vis-viva SMA prediction (< 5% error)
- CAM evaluate internal consistency check
- Documents that linear along-track shift model is a first-order
approximation only — GMAT shows the real effect is an SMA change.

These failures are intentional — they document what needs to be fixed
before the libraries are mission-ready.

+83 -18
+83 -18
lib/crc.ml
··· 57 57 (* {1 CRC-32} 58 58 59 59 All CRC-32 variants use Int32 arithmetic so they work on both 60 - 64-bit native OCaml and 32-bit targets (js_of_ocaml, wasm). *) 60 + 64-bit native OCaml and 32-bit targets (js_of_ocaml, wasm). 61 + 62 + Slicing-by-8: processes 8 bytes per iteration using 8 x 256-entry 63 + tables (8 KB per polynomial). Same technique as Go hash/crc32 and 64 + Rust crc32fast baseline. Falls back to byte-at-a-time for the 65 + remaining 0-7 bytes. *) 61 66 62 67 module C32 = struct 63 68 let ( lxor ) = Int32.logxor 64 69 let ( land ) = Int32.logand 65 70 let ( lsr ) = Int32.shift_right_logical 66 71 72 + (* Int32.to_int sign-extends on 64-bit; mask to get unsigned. *) 73 + let to_unsigned_int x = Stdlib.(Int32.to_int x land 0xFFFFFFFF) 74 + 75 + (* Extract byte k (0=low, 3=high) from an int32, as a native int. *) 76 + let byte_of v k = 77 + let open Stdlib in 78 + Int32.to_int (Int32.shift_right_logical v (k * 8)) land 0xFF 79 + 67 80 let make_table poly = 68 81 Array.init 256 (fun i -> 69 82 let crc = ref (Int32.of_int i) in ··· 73 86 done; 74 87 !crc) 75 88 76 - let compute table data = 89 + let make_slicing_tables poly = 90 + let t = Array.init 8 (fun _ -> Array.make 256 0l) in 91 + t.(0) <- make_table poly; 92 + for i = 0 to 255 do 93 + let crc = ref t.(0).(i) in 94 + for j = 1 to 7 do 95 + crc := t.(0).(Int32.to_int (!crc land 0xFFl)) lxor (!crc lsr 8); 96 + t.(j).(i) <- !crc 97 + done 98 + done; 99 + t 100 + 101 + let slice8 t get buf crc p = 102 + let b0 = Char.code (get buf p) in 103 + let b1 = Char.code (get buf Stdlib.(p + 1)) in 104 + let b2 = Char.code (get buf Stdlib.(p + 2)) in 105 + let b3 = Char.code (get buf Stdlib.(p + 3)) in 106 + let b4 = Char.code (get buf Stdlib.(p + 4)) in 107 + let b5 = Char.code (get buf Stdlib.(p + 5)) in 108 + let b6 = Char.code (get buf Stdlib.(p + 6)) in 109 + let b7 = Char.code (get buf Stdlib.(p + 7)) in 110 + let c = !crc in 111 + let c0 = Stdlib.(byte_of c 0 lxor b0) in 112 + let c1 = Stdlib.(byte_of c 1 lxor b1) in 113 + let c2 = Stdlib.(byte_of c 2 lxor b2) in 114 + let c3 = Stdlib.(byte_of c 3 lxor b3) in 115 + crc := 116 + t.(7).(c0) 117 + lxor t.(6).(c1) 118 + lxor t.(5).(c2) 119 + lxor t.(4).(c3) 120 + lxor t.(3).(b4) 121 + lxor t.(2).(b5) 122 + lxor t.(1).(b6) 123 + lxor t.(0).(b7) 124 + 125 + let tail1 t get buf crc i = 126 + let byte = Int32.of_int (Char.code (get buf !i)) in 127 + let idx = Int32.to_int (!crc lxor byte land 0xFFl) in 128 + crc := t.(0).(idx) lxor (!crc lsr 8); 129 + incr i 130 + 131 + let compute tables data = 132 + let t = tables in 133 + let len = String.length data in 77 134 let crc = ref 0xFFFFFFFFl in 78 - for i = 0 to String.length data - 1 do 79 - let byte = Int32.of_int (Char.code (String.unsafe_get data i)) in 80 - let idx = Int32.to_int (!crc lxor byte land 0xFFl) in 81 - crc := table.(idx) lxor (!crc lsr 8) 135 + let i = ref 0 in 136 + while Stdlib.(!i + 8 <= len) do 137 + slice8 t String.unsafe_get data crc !i; 138 + i := Stdlib.(!i + 8) 82 139 done; 83 - Int32.to_int (!crc lxor 0xFFFFFFFFl) 140 + while Stdlib.(!i < len) do 141 + tail1 t String.unsafe_get data crc i 142 + done; 143 + to_unsigned_int (!crc lxor 0xFFFFFFFFl) 84 144 85 - let compute_bytes table buf off len = 145 + let compute_bytes tables buf off len = 146 + let t = tables in 86 147 let crc = ref 0xFFFFFFFFl in 87 - for i = off to off + len - 1 do 88 - let byte = Int32.of_int (Char.code (Bytes.unsafe_get buf i)) in 89 - let idx = Int32.to_int (!crc lxor byte land 0xFFl) in 90 - crc := table.(idx) lxor (!crc lsr 8) 148 + let i = ref off in 149 + let stop = Stdlib.(off + len) in 150 + while Stdlib.(!i + 8 <= stop) do 151 + slice8 t Bytes.unsafe_get buf crc !i; 152 + i := Stdlib.(!i + 8) 153 + done; 154 + while Stdlib.(!i < stop) do 155 + tail1 t Bytes.unsafe_get buf crc i 91 156 done; 92 - Int32.to_int (!crc lxor 0xFFFFFFFFl) 157 + to_unsigned_int (!crc lxor 0xFFFFFFFFl) 93 158 end 94 159 95 160 (* {2 CRC-32 (ISO 3309)} ··· 97 162 Polynomial: 0xEDB88320 (reflected form of 0x04C11DB7) 98 163 Init: 0xFFFFFFFF, XOR out: 0xFFFFFFFF. *) 99 164 100 - let crc32_table = C32.make_table 0xEDB88320l 101 - let crc32 data = C32.compute crc32_table data 165 + let crc32_tables = C32.make_slicing_tables 0xEDB88320l 166 + let crc32 data = C32.compute crc32_tables data 102 167 103 168 (* {2 CRC-32C (Castagnoli)} 104 169 ··· 106 171 Init: 0xFFFFFFFF, XOR out: 0xFFFFFFFF. 107 172 Used by iSCSI, ext4, Btrfs. *) 108 173 109 - let crc32c_table = C32.make_table 0x82F63B78l 110 - let crc32c data = C32.compute crc32c_table data 111 - let crc32c_bytes buf off len = C32.compute_bytes crc32c_table buf off len 174 + let crc32c_tables = C32.make_slicing_tables 0x82F63B78l 175 + let crc32c data = C32.compute crc32c_tables data 176 + let crc32c_bytes buf off len = C32.compute_bytes crc32c_tables buf off len