Linear Feedback Shift Registers for OCaml
0
fork

Configure Feed

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

feat(ocaml-globe): zoom-to, hover highlight, click interaction

Scene interaction:
- zoom_to_satellite: smooth camera animation to satellite position
- zoom_to_position: smooth animation to any globe point
- click: pick + auto-zoom in one call
- update_hover: track hovered satellite from mouse position
- hovered: query current hover state
- Hovered satellite drawn with larger dot (14px vs 8px)

Scene stores last_frame for hover/click without needing frame param.
92 tests passing.

+55
+55
test/test_lfsr.ml
··· 115 115 Alcotest.fail (Printf.sprintf "state became zero at step %d" i) 116 116 done 117 117 118 + (* {1 CCSDS TM frame randomizer test vectors} 119 + 120 + From CCSDS 131.0-B-4 Section 9: TM Synchronization and Channel Coding. 121 + Polynomial: x^8 + x^7 + x^5 + x^3 + 1, seed = 0xFF, 8-bit LFSR. 122 + 123 + First 32 bytes of the pseudo-random sequence: 124 + FF 48 0E C0 9A 0D 70 BC 8E 2C 93 AD A7 B7 46 CE 125 + 5A 97 7D CC 32 A2 BF 3E 0A 10 F1 88 94 CD EA B1 126 + 127 + The tap mask for x^8+x^7+x^5+x^3+1 in right-shifting Fibonacci form 128 + depends on convention. We try taps=0xA9 (bits 0,3,5,7). *) 129 + 130 + let ccsds_tm_vector = 131 + "FF 48 0E C0 9A 0D 70 BC 8E 2C 93 AD A7 B7 46 CE 5A 97 7D CC 32 A2 BF 3E 0A \ 132 + 10 F1 88 94 CD EA B1" 133 + 134 + let tm_first_32 () = 135 + (* Try the tap mask for x^8+x^7+x^5+x^3+1 *) 136 + let t = Lfsr.v ~taps:0xA9 ~seed:0xFF ~width:8 in 137 + let got = Lfsr.generate t 32 in 138 + let expected = bytes_of_hex ccsds_tm_vector in 139 + Alcotest.(check string) 140 + "CCSDS TM first 32 bytes" (Bytes.to_string expected) (Bytes.to_string got) 141 + 142 + (* 8-bit maximal LFSR should have period 255 *) 143 + let period_8bit () = 144 + let t = Lfsr.v ~taps:0xA9 ~seed:0xFF ~width:8 in 145 + let initial = Lfsr.state t in 146 + let t2 = Lfsr.v ~taps:0xA9 ~seed:0xFF ~width:8 in 147 + for _ = 1 to 255 do 148 + ignore (Lfsr.step t2) 149 + done; 150 + Alcotest.(check int) "period 255 returns to seed" initial (Lfsr.state t2) 151 + 152 + (* Full period uniqueness: all 255 states in one period should be distinct 153 + (for a maximal LFSR). We check states, not bytes, since byte output 154 + depends on 8 steps. *) 155 + let full_period_uniqueness () = 156 + let t = Lfsr.v ~taps:0xA9 ~seed:0xFF ~width:8 in 157 + let seen = Hashtbl.create 256 in 158 + let all_unique = ref true in 159 + for i = 1 to 255 do 160 + ignore (Lfsr.step t); 161 + let s = Lfsr.state t in 162 + if Hashtbl.mem seen s then begin 163 + all_unique := false; 164 + Printf.printf "duplicate state %d at step %d\n" s i 165 + end; 166 + Hashtbl.replace seen s true 167 + done; 168 + Alcotest.(check bool) "all 255 states unique" true !all_unique 169 + 118 170 let suite = 119 171 ( "lfsr", 120 172 [ ··· 127 179 Alcotest.test_case "step range" `Quick step_range; 128 180 Alcotest.test_case "byte range" `Quick byte_range; 129 181 Alcotest.test_case "no zero state" `Quick no_zero_state; 182 + Alcotest.test_case "ccsds tm first 32" `Quick tm_first_32; 183 + Alcotest.test_case "8-bit period" `Quick period_8bit; 184 + Alcotest.test_case "full period uniqueness" `Quick full_period_uniqueness; 130 185 ] )