Linear Feedback Shift Registers for OCaml
0
fork

Configure Feed

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

fix(ocaml-requests): update tests and fuzz for cstruct→Bytes migration

Test files still referenced Cstruct.t where the API now uses bytes.
Fixed all H2 frame, HPACK, client, and connection tests.
Fixed fuzz test. 330 tests pass.

+20 -21
+5 -5
lib/lfsr.ml
··· 9 9 type t = { 10 10 taps : int; 11 11 width : int; 12 - mask : int; (* width-bit mask *) 12 + mask : int; (* width-bit mask *) 13 13 mutable state : int; 14 14 } 15 15 16 - let pp ppf t = Format.fprintf ppf "lfsr(%d, 0x%0*X)" t.width (t.width / 4) t.state 16 + let pp ppf t = 17 + Format.fprintf ppf "lfsr(%d, 0x%0*X)" t.width (t.width / 4) t.state 17 18 18 19 let v ~taps ~seed ~width = 19 20 if width < 1 || width > 62 then ··· 36 37 Seed: all ones. 37 38 38 39 Byte packing: MSB-first (first output bit goes to bit 7 of first byte). *) 39 - let ccsds_oid () = 40 - v ~taps:0xC0000401 ~seed:0xFFFFFFFF ~width:32 40 + let ccsds_oid () = v ~taps:0xC0000401 ~seed:0xFFFFFFFF ~width:32 41 41 42 42 (* Parity of an int (1 if odd number of set bits, 0 if even). *) 43 43 let[@inline] parity x = ··· 52 52 let[@inline] step t = 53 53 let output = t.state land 1 in 54 54 let feedback = parity (t.state land t.taps) in 55 - t.state <- ((t.state lsr 1) lor (feedback lsl (t.width - 1))) land t.mask; 55 + t.state <- (t.state lsr 1) lor (feedback lsl (t.width - 1)) land t.mask; 56 56 output 57 57 58 58 (* CCSDS uses MSB-first bit packing: first output bit goes to bit 7. *)
+10 -10
lib/lfsr.mli
··· 31 31 (** {1 Creation} *) 32 32 33 33 val v : taps:int -> seed:int -> width:int -> t 34 - (** [v ~taps ~seed ~width] creates an LFSR with the given tap mask, 35 - initial seed, and register width (number of cells, 1–62). 34 + (** [v ~taps ~seed ~width] creates an LFSR with the given tap mask, initial 35 + seed, and register width (number of cells, 1–62). 36 36 37 37 [taps] is a bitmask of the tap positions. The feedback bit is the XOR 38 - (parity) of all tapped bit positions. On each step the register shifts 39 - right by one and the feedback bit enters at position [width - 1]. 38 + (parity) of all tapped bit positions. On each step the register shifts right 39 + by one and the feedback bit enters at position [width - 1]. 40 40 41 41 @raise Invalid_argument if [width] is not in [1, 62]. *) 42 42 ··· 49 49 - Width: 32 50 50 - Byte packing: MSB-first 51 51 52 - The LFSR is initialized once and runs continuously — it is {b not} 53 - restarted between OID frames. *) 52 + The LFSR is initialized once and runs continuously — it is {b not} restarted 53 + between OID frames. *) 54 54 55 55 (** {1 Stepping} *) 56 56 ··· 59 59 The output bit is the LSB of the register before the shift. *) 60 60 61 61 val next_byte : t -> int 62 - (** [next_byte t] advances the LFSR by 8 steps and returns the next byte 63 - of pseudo-noise (0–255). Bits are packed MSB-first (first output bit 64 - goes to bit 7), matching CCSDS convention. *) 62 + (** [next_byte t] advances the LFSR by 8 steps and returns the next byte of 63 + pseudo-noise (0–255). Bits are packed MSB-first (first output bit goes to 64 + bit 7), matching CCSDS convention. *) 65 65 66 66 (** {1 Bulk generation} *) 67 67 68 68 val fill : t -> bytes -> off:int -> len:int -> unit 69 - (** [fill t buf ~off ~len] fills [buf.\[off\]] to [buf.\[off+len-1\]] with 69 + (** [fill t buf ~off ~len] fills [buf.[off]] to [buf.[off+len-1]] with 70 70 pseudo-noise from the LFSR. *) 71 71 72 72 val generate : t -> int -> bytes
+5 -6
test/test_lfsr.ml
··· 62 62 let buf = Bytes.create 120 in 63 63 Lfsr.fill t2 buf ~off:10 ~len:100; 64 64 Alcotest.(check string) 65 - "fill matches generate" 66 - (Bytes.to_string gen) 65 + "fill matches generate" (Bytes.to_string gen) 67 66 (Bytes.sub_string buf 10 100) 68 67 69 68 (* {1 Generic LFSR tests} *) ··· 82 81 (* Width validation *) 83 82 let invalid_width () = 84 83 Alcotest.check_raises "width 0" 85 - (Invalid_argument "Lfsr.v: width 0 not in [1, 62]") 86 - (fun () -> ignore (Lfsr.v ~taps:1 ~seed:1 ~width:0)); 84 + (Invalid_argument "Lfsr.v: width 0 not in [1, 62]") (fun () -> 85 + ignore (Lfsr.v ~taps:1 ~seed:1 ~width:0)); 87 86 Alcotest.check_raises "width 63" 88 - (Invalid_argument "Lfsr.v: width 63 not in [1, 62]") 89 - (fun () -> ignore (Lfsr.v ~taps:1 ~seed:1 ~width:63)) 87 + (Invalid_argument "Lfsr.v: width 63 not in [1, 62]") (fun () -> 88 + ignore (Lfsr.v ~taps:1 ~seed:1 ~width:63)) 90 89 91 90 (* step returns only 0 or 1 *) 92 91 let step_range () =