oscura 0.0.1__py3-none-any.whl → 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. oscura/__init__.py +813 -8
  2. oscura/__main__.py +392 -0
  3. oscura/analyzers/__init__.py +37 -0
  4. oscura/analyzers/digital/__init__.py +177 -0
  5. oscura/analyzers/digital/bus.py +691 -0
  6. oscura/analyzers/digital/clock.py +805 -0
  7. oscura/analyzers/digital/correlation.py +720 -0
  8. oscura/analyzers/digital/edges.py +632 -0
  9. oscura/analyzers/digital/extraction.py +413 -0
  10. oscura/analyzers/digital/quality.py +878 -0
  11. oscura/analyzers/digital/signal_quality.py +877 -0
  12. oscura/analyzers/digital/thresholds.py +708 -0
  13. oscura/analyzers/digital/timing.py +1104 -0
  14. oscura/analyzers/eye/__init__.py +46 -0
  15. oscura/analyzers/eye/diagram.py +434 -0
  16. oscura/analyzers/eye/metrics.py +555 -0
  17. oscura/analyzers/jitter/__init__.py +83 -0
  18. oscura/analyzers/jitter/ber.py +333 -0
  19. oscura/analyzers/jitter/decomposition.py +759 -0
  20. oscura/analyzers/jitter/measurements.py +413 -0
  21. oscura/analyzers/jitter/spectrum.py +220 -0
  22. oscura/analyzers/measurements.py +40 -0
  23. oscura/analyzers/packet/__init__.py +171 -0
  24. oscura/analyzers/packet/daq.py +1077 -0
  25. oscura/analyzers/packet/metrics.py +437 -0
  26. oscura/analyzers/packet/parser.py +327 -0
  27. oscura/analyzers/packet/payload.py +2156 -0
  28. oscura/analyzers/packet/payload_analysis.py +1312 -0
  29. oscura/analyzers/packet/payload_extraction.py +236 -0
  30. oscura/analyzers/packet/payload_patterns.py +670 -0
  31. oscura/analyzers/packet/stream.py +359 -0
  32. oscura/analyzers/patterns/__init__.py +266 -0
  33. oscura/analyzers/patterns/clustering.py +1036 -0
  34. oscura/analyzers/patterns/discovery.py +539 -0
  35. oscura/analyzers/patterns/learning.py +797 -0
  36. oscura/analyzers/patterns/matching.py +1091 -0
  37. oscura/analyzers/patterns/periodic.py +650 -0
  38. oscura/analyzers/patterns/sequences.py +767 -0
  39. oscura/analyzers/power/__init__.py +116 -0
  40. oscura/analyzers/power/ac_power.py +391 -0
  41. oscura/analyzers/power/basic.py +383 -0
  42. oscura/analyzers/power/conduction.py +314 -0
  43. oscura/analyzers/power/efficiency.py +297 -0
  44. oscura/analyzers/power/ripple.py +356 -0
  45. oscura/analyzers/power/soa.py +372 -0
  46. oscura/analyzers/power/switching.py +479 -0
  47. oscura/analyzers/protocol/__init__.py +150 -0
  48. oscura/analyzers/protocols/__init__.py +150 -0
  49. oscura/analyzers/protocols/base.py +500 -0
  50. oscura/analyzers/protocols/can.py +620 -0
  51. oscura/analyzers/protocols/can_fd.py +448 -0
  52. oscura/analyzers/protocols/flexray.py +405 -0
  53. oscura/analyzers/protocols/hdlc.py +399 -0
  54. oscura/analyzers/protocols/i2c.py +368 -0
  55. oscura/analyzers/protocols/i2s.py +296 -0
  56. oscura/analyzers/protocols/jtag.py +393 -0
  57. oscura/analyzers/protocols/lin.py +445 -0
  58. oscura/analyzers/protocols/manchester.py +333 -0
  59. oscura/analyzers/protocols/onewire.py +501 -0
  60. oscura/analyzers/protocols/spi.py +334 -0
  61. oscura/analyzers/protocols/swd.py +325 -0
  62. oscura/analyzers/protocols/uart.py +393 -0
  63. oscura/analyzers/protocols/usb.py +495 -0
  64. oscura/analyzers/signal_integrity/__init__.py +63 -0
  65. oscura/analyzers/signal_integrity/embedding.py +294 -0
  66. oscura/analyzers/signal_integrity/equalization.py +370 -0
  67. oscura/analyzers/signal_integrity/sparams.py +484 -0
  68. oscura/analyzers/spectral/__init__.py +53 -0
  69. oscura/analyzers/spectral/chunked.py +273 -0
  70. oscura/analyzers/spectral/chunked_fft.py +571 -0
  71. oscura/analyzers/spectral/chunked_wavelet.py +391 -0
  72. oscura/analyzers/spectral/fft.py +92 -0
  73. oscura/analyzers/statistical/__init__.py +250 -0
  74. oscura/analyzers/statistical/checksum.py +923 -0
  75. oscura/analyzers/statistical/chunked_corr.py +228 -0
  76. oscura/analyzers/statistical/classification.py +778 -0
  77. oscura/analyzers/statistical/entropy.py +1113 -0
  78. oscura/analyzers/statistical/ngrams.py +614 -0
  79. oscura/analyzers/statistics/__init__.py +119 -0
  80. oscura/analyzers/statistics/advanced.py +885 -0
  81. oscura/analyzers/statistics/basic.py +263 -0
  82. oscura/analyzers/statistics/correlation.py +630 -0
  83. oscura/analyzers/statistics/distribution.py +298 -0
  84. oscura/analyzers/statistics/outliers.py +463 -0
  85. oscura/analyzers/statistics/streaming.py +93 -0
  86. oscura/analyzers/statistics/trend.py +520 -0
  87. oscura/analyzers/validation.py +598 -0
  88. oscura/analyzers/waveform/__init__.py +36 -0
  89. oscura/analyzers/waveform/measurements.py +943 -0
  90. oscura/analyzers/waveform/measurements_with_uncertainty.py +371 -0
  91. oscura/analyzers/waveform/spectral.py +1689 -0
  92. oscura/analyzers/waveform/wavelets.py +298 -0
  93. oscura/api/__init__.py +62 -0
  94. oscura/api/dsl.py +538 -0
  95. oscura/api/fluent.py +571 -0
  96. oscura/api/operators.py +498 -0
  97. oscura/api/optimization.py +392 -0
  98. oscura/api/profiling.py +396 -0
  99. oscura/automotive/__init__.py +73 -0
  100. oscura/automotive/can/__init__.py +52 -0
  101. oscura/automotive/can/analysis.py +356 -0
  102. oscura/automotive/can/checksum.py +250 -0
  103. oscura/automotive/can/correlation.py +212 -0
  104. oscura/automotive/can/discovery.py +355 -0
  105. oscura/automotive/can/message_wrapper.py +375 -0
  106. oscura/automotive/can/models.py +385 -0
  107. oscura/automotive/can/patterns.py +381 -0
  108. oscura/automotive/can/session.py +452 -0
  109. oscura/automotive/can/state_machine.py +300 -0
  110. oscura/automotive/can/stimulus_response.py +461 -0
  111. oscura/automotive/dbc/__init__.py +15 -0
  112. oscura/automotive/dbc/generator.py +156 -0
  113. oscura/automotive/dbc/parser.py +146 -0
  114. oscura/automotive/dtc/__init__.py +30 -0
  115. oscura/automotive/dtc/database.py +3036 -0
  116. oscura/automotive/j1939/__init__.py +14 -0
  117. oscura/automotive/j1939/decoder.py +745 -0
  118. oscura/automotive/loaders/__init__.py +35 -0
  119. oscura/automotive/loaders/asc.py +98 -0
  120. oscura/automotive/loaders/blf.py +77 -0
  121. oscura/automotive/loaders/csv_can.py +136 -0
  122. oscura/automotive/loaders/dispatcher.py +136 -0
  123. oscura/automotive/loaders/mdf.py +331 -0
  124. oscura/automotive/loaders/pcap.py +132 -0
  125. oscura/automotive/obd/__init__.py +14 -0
  126. oscura/automotive/obd/decoder.py +707 -0
  127. oscura/automotive/uds/__init__.py +48 -0
  128. oscura/automotive/uds/decoder.py +265 -0
  129. oscura/automotive/uds/models.py +64 -0
  130. oscura/automotive/visualization.py +369 -0
  131. oscura/batch/__init__.py +55 -0
  132. oscura/batch/advanced.py +627 -0
  133. oscura/batch/aggregate.py +300 -0
  134. oscura/batch/analyze.py +139 -0
  135. oscura/batch/logging.py +487 -0
  136. oscura/batch/metrics.py +556 -0
  137. oscura/builders/__init__.py +41 -0
  138. oscura/builders/signal_builder.py +1131 -0
  139. oscura/cli/__init__.py +14 -0
  140. oscura/cli/batch.py +339 -0
  141. oscura/cli/characterize.py +273 -0
  142. oscura/cli/compare.py +775 -0
  143. oscura/cli/decode.py +551 -0
  144. oscura/cli/main.py +247 -0
  145. oscura/cli/shell.py +350 -0
  146. oscura/comparison/__init__.py +66 -0
  147. oscura/comparison/compare.py +397 -0
  148. oscura/comparison/golden.py +487 -0
  149. oscura/comparison/limits.py +391 -0
  150. oscura/comparison/mask.py +434 -0
  151. oscura/comparison/trace_diff.py +30 -0
  152. oscura/comparison/visualization.py +481 -0
  153. oscura/compliance/__init__.py +70 -0
  154. oscura/compliance/advanced.py +756 -0
  155. oscura/compliance/masks.py +363 -0
  156. oscura/compliance/reporting.py +483 -0
  157. oscura/compliance/testing.py +298 -0
  158. oscura/component/__init__.py +38 -0
  159. oscura/component/impedance.py +365 -0
  160. oscura/component/reactive.py +598 -0
  161. oscura/component/transmission_line.py +312 -0
  162. oscura/config/__init__.py +191 -0
  163. oscura/config/defaults.py +254 -0
  164. oscura/config/loader.py +348 -0
  165. oscura/config/memory.py +271 -0
  166. oscura/config/migration.py +458 -0
  167. oscura/config/pipeline.py +1077 -0
  168. oscura/config/preferences.py +530 -0
  169. oscura/config/protocol.py +875 -0
  170. oscura/config/schema.py +713 -0
  171. oscura/config/settings.py +420 -0
  172. oscura/config/thresholds.py +599 -0
  173. oscura/convenience.py +457 -0
  174. oscura/core/__init__.py +299 -0
  175. oscura/core/audit.py +457 -0
  176. oscura/core/backend_selector.py +405 -0
  177. oscura/core/cache.py +590 -0
  178. oscura/core/cancellation.py +439 -0
  179. oscura/core/confidence.py +225 -0
  180. oscura/core/config.py +506 -0
  181. oscura/core/correlation.py +216 -0
  182. oscura/core/cross_domain.py +422 -0
  183. oscura/core/debug.py +301 -0
  184. oscura/core/edge_cases.py +541 -0
  185. oscura/core/exceptions.py +535 -0
  186. oscura/core/gpu_backend.py +523 -0
  187. oscura/core/lazy.py +832 -0
  188. oscura/core/log_query.py +540 -0
  189. oscura/core/logging.py +931 -0
  190. oscura/core/logging_advanced.py +952 -0
  191. oscura/core/memoize.py +171 -0
  192. oscura/core/memory_check.py +274 -0
  193. oscura/core/memory_guard.py +290 -0
  194. oscura/core/memory_limits.py +336 -0
  195. oscura/core/memory_monitor.py +453 -0
  196. oscura/core/memory_progress.py +465 -0
  197. oscura/core/memory_warnings.py +315 -0
  198. oscura/core/numba_backend.py +362 -0
  199. oscura/core/performance.py +352 -0
  200. oscura/core/progress.py +524 -0
  201. oscura/core/provenance.py +358 -0
  202. oscura/core/results.py +331 -0
  203. oscura/core/types.py +504 -0
  204. oscura/core/uncertainty.py +383 -0
  205. oscura/discovery/__init__.py +52 -0
  206. oscura/discovery/anomaly_detector.py +672 -0
  207. oscura/discovery/auto_decoder.py +415 -0
  208. oscura/discovery/comparison.py +497 -0
  209. oscura/discovery/quality_validator.py +528 -0
  210. oscura/discovery/signal_detector.py +769 -0
  211. oscura/dsl/__init__.py +73 -0
  212. oscura/dsl/commands.py +246 -0
  213. oscura/dsl/interpreter.py +455 -0
  214. oscura/dsl/parser.py +689 -0
  215. oscura/dsl/repl.py +172 -0
  216. oscura/exceptions.py +59 -0
  217. oscura/exploratory/__init__.py +111 -0
  218. oscura/exploratory/error_recovery.py +642 -0
  219. oscura/exploratory/fuzzy.py +513 -0
  220. oscura/exploratory/fuzzy_advanced.py +786 -0
  221. oscura/exploratory/legacy.py +831 -0
  222. oscura/exploratory/parse.py +358 -0
  223. oscura/exploratory/recovery.py +275 -0
  224. oscura/exploratory/sync.py +382 -0
  225. oscura/exploratory/unknown.py +707 -0
  226. oscura/export/__init__.py +25 -0
  227. oscura/export/wireshark/README.md +265 -0
  228. oscura/export/wireshark/__init__.py +47 -0
  229. oscura/export/wireshark/generator.py +312 -0
  230. oscura/export/wireshark/lua_builder.py +159 -0
  231. oscura/export/wireshark/templates/dissector.lua.j2 +92 -0
  232. oscura/export/wireshark/type_mapping.py +165 -0
  233. oscura/export/wireshark/validator.py +105 -0
  234. oscura/exporters/__init__.py +94 -0
  235. oscura/exporters/csv.py +303 -0
  236. oscura/exporters/exporters.py +44 -0
  237. oscura/exporters/hdf5.py +219 -0
  238. oscura/exporters/html_export.py +701 -0
  239. oscura/exporters/json_export.py +291 -0
  240. oscura/exporters/markdown_export.py +367 -0
  241. oscura/exporters/matlab_export.py +354 -0
  242. oscura/exporters/npz_export.py +219 -0
  243. oscura/exporters/spice_export.py +210 -0
  244. oscura/extensibility/__init__.py +131 -0
  245. oscura/extensibility/docs.py +752 -0
  246. oscura/extensibility/extensions.py +1125 -0
  247. oscura/extensibility/logging.py +259 -0
  248. oscura/extensibility/measurements.py +485 -0
  249. oscura/extensibility/plugins.py +414 -0
  250. oscura/extensibility/registry.py +346 -0
  251. oscura/extensibility/templates.py +913 -0
  252. oscura/extensibility/validation.py +651 -0
  253. oscura/filtering/__init__.py +89 -0
  254. oscura/filtering/base.py +563 -0
  255. oscura/filtering/convenience.py +564 -0
  256. oscura/filtering/design.py +725 -0
  257. oscura/filtering/filters.py +32 -0
  258. oscura/filtering/introspection.py +605 -0
  259. oscura/guidance/__init__.py +24 -0
  260. oscura/guidance/recommender.py +429 -0
  261. oscura/guidance/wizard.py +518 -0
  262. oscura/inference/__init__.py +251 -0
  263. oscura/inference/active_learning/README.md +153 -0
  264. oscura/inference/active_learning/__init__.py +38 -0
  265. oscura/inference/active_learning/lstar.py +257 -0
  266. oscura/inference/active_learning/observation_table.py +230 -0
  267. oscura/inference/active_learning/oracle.py +78 -0
  268. oscura/inference/active_learning/teachers/__init__.py +15 -0
  269. oscura/inference/active_learning/teachers/simulator.py +192 -0
  270. oscura/inference/adaptive_tuning.py +453 -0
  271. oscura/inference/alignment.py +653 -0
  272. oscura/inference/bayesian.py +943 -0
  273. oscura/inference/binary.py +1016 -0
  274. oscura/inference/crc_reverse.py +711 -0
  275. oscura/inference/logic.py +288 -0
  276. oscura/inference/message_format.py +1305 -0
  277. oscura/inference/protocol.py +417 -0
  278. oscura/inference/protocol_dsl.py +1084 -0
  279. oscura/inference/protocol_library.py +1230 -0
  280. oscura/inference/sequences.py +809 -0
  281. oscura/inference/signal_intelligence.py +1509 -0
  282. oscura/inference/spectral.py +215 -0
  283. oscura/inference/state_machine.py +634 -0
  284. oscura/inference/stream.py +918 -0
  285. oscura/integrations/__init__.py +59 -0
  286. oscura/integrations/llm.py +1827 -0
  287. oscura/jupyter/__init__.py +32 -0
  288. oscura/jupyter/display.py +268 -0
  289. oscura/jupyter/magic.py +334 -0
  290. oscura/loaders/__init__.py +526 -0
  291. oscura/loaders/binary.py +69 -0
  292. oscura/loaders/configurable.py +1255 -0
  293. oscura/loaders/csv.py +26 -0
  294. oscura/loaders/csv_loader.py +473 -0
  295. oscura/loaders/hdf5.py +9 -0
  296. oscura/loaders/hdf5_loader.py +510 -0
  297. oscura/loaders/lazy.py +370 -0
  298. oscura/loaders/mmap_loader.py +583 -0
  299. oscura/loaders/numpy_loader.py +436 -0
  300. oscura/loaders/pcap.py +432 -0
  301. oscura/loaders/preprocessing.py +368 -0
  302. oscura/loaders/rigol.py +287 -0
  303. oscura/loaders/sigrok.py +321 -0
  304. oscura/loaders/tdms.py +367 -0
  305. oscura/loaders/tektronix.py +711 -0
  306. oscura/loaders/validation.py +584 -0
  307. oscura/loaders/vcd.py +464 -0
  308. oscura/loaders/wav.py +233 -0
  309. oscura/math/__init__.py +45 -0
  310. oscura/math/arithmetic.py +824 -0
  311. oscura/math/interpolation.py +413 -0
  312. oscura/onboarding/__init__.py +39 -0
  313. oscura/onboarding/help.py +498 -0
  314. oscura/onboarding/tutorials.py +405 -0
  315. oscura/onboarding/wizard.py +466 -0
  316. oscura/optimization/__init__.py +19 -0
  317. oscura/optimization/parallel.py +440 -0
  318. oscura/optimization/search.py +532 -0
  319. oscura/pipeline/__init__.py +43 -0
  320. oscura/pipeline/base.py +338 -0
  321. oscura/pipeline/composition.py +242 -0
  322. oscura/pipeline/parallel.py +448 -0
  323. oscura/pipeline/pipeline.py +375 -0
  324. oscura/pipeline/reverse_engineering.py +1119 -0
  325. oscura/plugins/__init__.py +122 -0
  326. oscura/plugins/base.py +272 -0
  327. oscura/plugins/cli.py +497 -0
  328. oscura/plugins/discovery.py +411 -0
  329. oscura/plugins/isolation.py +418 -0
  330. oscura/plugins/lifecycle.py +959 -0
  331. oscura/plugins/manager.py +493 -0
  332. oscura/plugins/registry.py +421 -0
  333. oscura/plugins/versioning.py +372 -0
  334. oscura/py.typed +0 -0
  335. oscura/quality/__init__.py +65 -0
  336. oscura/quality/ensemble.py +740 -0
  337. oscura/quality/explainer.py +338 -0
  338. oscura/quality/scoring.py +616 -0
  339. oscura/quality/warnings.py +456 -0
  340. oscura/reporting/__init__.py +248 -0
  341. oscura/reporting/advanced.py +1234 -0
  342. oscura/reporting/analyze.py +448 -0
  343. oscura/reporting/argument_preparer.py +596 -0
  344. oscura/reporting/auto_report.py +507 -0
  345. oscura/reporting/batch.py +615 -0
  346. oscura/reporting/chart_selection.py +223 -0
  347. oscura/reporting/comparison.py +330 -0
  348. oscura/reporting/config.py +615 -0
  349. oscura/reporting/content/__init__.py +39 -0
  350. oscura/reporting/content/executive.py +127 -0
  351. oscura/reporting/content/filtering.py +191 -0
  352. oscura/reporting/content/minimal.py +257 -0
  353. oscura/reporting/content/verbosity.py +162 -0
  354. oscura/reporting/core.py +508 -0
  355. oscura/reporting/core_formats/__init__.py +17 -0
  356. oscura/reporting/core_formats/multi_format.py +210 -0
  357. oscura/reporting/engine.py +836 -0
  358. oscura/reporting/export.py +366 -0
  359. oscura/reporting/formatting/__init__.py +129 -0
  360. oscura/reporting/formatting/emphasis.py +81 -0
  361. oscura/reporting/formatting/numbers.py +403 -0
  362. oscura/reporting/formatting/standards.py +55 -0
  363. oscura/reporting/formatting.py +466 -0
  364. oscura/reporting/html.py +578 -0
  365. oscura/reporting/index.py +590 -0
  366. oscura/reporting/multichannel.py +296 -0
  367. oscura/reporting/output.py +379 -0
  368. oscura/reporting/pdf.py +373 -0
  369. oscura/reporting/plots.py +731 -0
  370. oscura/reporting/pptx_export.py +360 -0
  371. oscura/reporting/renderers/__init__.py +11 -0
  372. oscura/reporting/renderers/pdf.py +94 -0
  373. oscura/reporting/sections.py +471 -0
  374. oscura/reporting/standards.py +680 -0
  375. oscura/reporting/summary_generator.py +368 -0
  376. oscura/reporting/tables.py +397 -0
  377. oscura/reporting/template_system.py +724 -0
  378. oscura/reporting/templates/__init__.py +15 -0
  379. oscura/reporting/templates/definition.py +205 -0
  380. oscura/reporting/templates/index.html +649 -0
  381. oscura/reporting/templates/index.md +173 -0
  382. oscura/schemas/__init__.py +158 -0
  383. oscura/schemas/bus_configuration.json +322 -0
  384. oscura/schemas/device_mapping.json +182 -0
  385. oscura/schemas/packet_format.json +418 -0
  386. oscura/schemas/protocol_definition.json +363 -0
  387. oscura/search/__init__.py +16 -0
  388. oscura/search/anomaly.py +292 -0
  389. oscura/search/context.py +149 -0
  390. oscura/search/pattern.py +160 -0
  391. oscura/session/__init__.py +34 -0
  392. oscura/session/annotations.py +289 -0
  393. oscura/session/history.py +313 -0
  394. oscura/session/session.py +445 -0
  395. oscura/streaming/__init__.py +43 -0
  396. oscura/streaming/chunked.py +611 -0
  397. oscura/streaming/progressive.py +393 -0
  398. oscura/streaming/realtime.py +622 -0
  399. oscura/testing/__init__.py +54 -0
  400. oscura/testing/synthetic.py +808 -0
  401. oscura/triggering/__init__.py +68 -0
  402. oscura/triggering/base.py +229 -0
  403. oscura/triggering/edge.py +353 -0
  404. oscura/triggering/pattern.py +344 -0
  405. oscura/triggering/pulse.py +581 -0
  406. oscura/triggering/window.py +453 -0
  407. oscura/ui/__init__.py +48 -0
  408. oscura/ui/formatters.py +526 -0
  409. oscura/ui/progressive_display.py +340 -0
  410. oscura/utils/__init__.py +99 -0
  411. oscura/utils/autodetect.py +338 -0
  412. oscura/utils/buffer.py +389 -0
  413. oscura/utils/lazy.py +407 -0
  414. oscura/utils/lazy_imports.py +147 -0
  415. oscura/utils/memory.py +836 -0
  416. oscura/utils/memory_advanced.py +1326 -0
  417. oscura/utils/memory_extensions.py +465 -0
  418. oscura/utils/progressive.py +352 -0
  419. oscura/utils/windowing.py +362 -0
  420. oscura/visualization/__init__.py +321 -0
  421. oscura/visualization/accessibility.py +526 -0
  422. oscura/visualization/annotations.py +374 -0
  423. oscura/visualization/axis_scaling.py +305 -0
  424. oscura/visualization/colors.py +453 -0
  425. oscura/visualization/digital.py +337 -0
  426. oscura/visualization/eye.py +420 -0
  427. oscura/visualization/histogram.py +281 -0
  428. oscura/visualization/interactive.py +858 -0
  429. oscura/visualization/jitter.py +702 -0
  430. oscura/visualization/keyboard.py +394 -0
  431. oscura/visualization/layout.py +365 -0
  432. oscura/visualization/optimization.py +1028 -0
  433. oscura/visualization/palettes.py +446 -0
  434. oscura/visualization/plot.py +92 -0
  435. oscura/visualization/power.py +290 -0
  436. oscura/visualization/power_extended.py +626 -0
  437. oscura/visualization/presets.py +467 -0
  438. oscura/visualization/protocols.py +932 -0
  439. oscura/visualization/render.py +207 -0
  440. oscura/visualization/rendering.py +444 -0
  441. oscura/visualization/reverse_engineering.py +791 -0
  442. oscura/visualization/signal_integrity.py +808 -0
  443. oscura/visualization/specialized.py +553 -0
  444. oscura/visualization/spectral.py +811 -0
  445. oscura/visualization/styles.py +381 -0
  446. oscura/visualization/thumbnails.py +311 -0
  447. oscura/visualization/time_axis.py +351 -0
  448. oscura/visualization/waveform.py +367 -0
  449. oscura/workflow/__init__.py +13 -0
  450. oscura/workflow/dag.py +377 -0
  451. oscura/workflows/__init__.py +58 -0
  452. oscura/workflows/compliance.py +280 -0
  453. oscura/workflows/digital.py +272 -0
  454. oscura/workflows/multi_trace.py +502 -0
  455. oscura/workflows/power.py +178 -0
  456. oscura/workflows/protocol.py +492 -0
  457. oscura/workflows/reverse_engineering.py +639 -0
  458. oscura/workflows/signal_integrity.py +227 -0
  459. oscura-0.1.1.dist-info/METADATA +300 -0
  460. oscura-0.1.1.dist-info/RECORD +463 -0
  461. oscura-0.1.1.dist-info/entry_points.txt +2 -0
  462. {oscura-0.0.1.dist-info → oscura-0.1.1.dist-info}/licenses/LICENSE +1 -1
  463. oscura-0.0.1.dist-info/METADATA +0 -63
  464. oscura-0.0.1.dist-info/RECORD +0 -5
  465. {oscura-0.0.1.dist-info → oscura-0.1.1.dist-info}/WHEEL +0 -0
@@ -0,0 +1,359 @@
1
+ """Stream processing utilities for packet analysis.
2
+
3
+ This module provides generator-based stream processing for
4
+ O(1) memory usage when analyzing large packet captures.
5
+
6
+
7
+ Example:
8
+ >>> from oscura.analyzers.packet.stream import stream_packets
9
+ >>> for packet in stream_packets(file_path, format="pcap"):
10
+ ... process(packet) # Process one at a time
11
+
12
+ References:
13
+ Python generators and itertools patterns
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import io
19
+ from dataclasses import dataclass
20
+ from pathlib import Path
21
+ from typing import TYPE_CHECKING, Any, BinaryIO, TypeVar
22
+
23
+ from oscura.analyzers.packet.parser import BinaryParser
24
+
25
+ if TYPE_CHECKING:
26
+ from collections.abc import Callable, Iterator
27
+
28
+ T = TypeVar("T")
29
+
30
+
31
+ @dataclass
32
+ class StreamPacket:
33
+ """Packet from a stream.
34
+
35
+ Attributes:
36
+ timestamp: Packet timestamp in seconds.
37
+ data: Raw packet data.
38
+ metadata: Additional packet metadata.
39
+ """
40
+
41
+ timestamp: float
42
+ data: bytes
43
+ metadata: dict[str, Any]
44
+
45
+
46
+ def stream_file(
47
+ file_path: str | Path,
48
+ chunk_size: int = 65536,
49
+ ) -> Iterator[bytes]:
50
+ """Stream file in chunks.
51
+
52
+ Args:
53
+ file_path: Path to file.
54
+ chunk_size: Bytes per chunk (default 64KB).
55
+
56
+ Yields:
57
+ Byte chunks from file.
58
+
59
+ Example:
60
+ >>> for chunk in stream_file("large_capture.bin"):
61
+ ... process_chunk(chunk)
62
+ """
63
+ path = Path(file_path)
64
+
65
+ with open(path, "rb") as f:
66
+ while True:
67
+ chunk = f.read(chunk_size)
68
+ if not chunk:
69
+ break
70
+ yield chunk
71
+
72
+
73
+ def stream_records(
74
+ file_or_buffer: str | Path | BinaryIO | bytes,
75
+ record_size: int,
76
+ ) -> Iterator[bytes]:
77
+ """Stream fixed-size records.
78
+
79
+ Args:
80
+ file_or_buffer: Source file path, file object, or bytes.
81
+ record_size: Size of each record in bytes.
82
+
83
+ Yields:
84
+ Records as bytes objects.
85
+
86
+ Example:
87
+ >>> for record in stream_records("data.bin", record_size=128):
88
+ ... parse_record(record)
89
+ """
90
+ if isinstance(file_or_buffer, bytes):
91
+ buffer: BinaryIO = io.BytesIO(file_or_buffer)
92
+ should_close = True
93
+ elif isinstance(file_or_buffer, str | Path):
94
+ buffer = open(file_or_buffer, "rb") # noqa: SIM115
95
+ should_close = True
96
+ else:
97
+ buffer = file_or_buffer
98
+ should_close = False
99
+
100
+ try:
101
+ while True:
102
+ record = buffer.read(record_size)
103
+ if len(record) < record_size:
104
+ break
105
+ yield record
106
+ finally:
107
+ if should_close:
108
+ buffer.close()
109
+
110
+
111
+ def stream_packets(
112
+ file_or_buffer: str | Path | BinaryIO | bytes,
113
+ *,
114
+ header_parser: BinaryParser | None = None,
115
+ length_field: int = 1,
116
+ header_included: bool = False,
117
+ ) -> Iterator[StreamPacket]:
118
+ """Stream variable-length packets.
119
+
120
+ Parses packets with length-prefixed format.
121
+
122
+ Args:
123
+ file_or_buffer: Source.
124
+ header_parser: Parser for packet header.
125
+ length_field: Index of length field in header (default 1).
126
+ header_included: True if length includes header.
127
+
128
+ Yields:
129
+ StreamPacket objects.
130
+
131
+ Example:
132
+ >>> header = BinaryParser(">HH") # sync, length
133
+ >>> for pkt in stream_packets("capture.bin", header_parser=header):
134
+ ... print(f"Packet: {len(pkt.data)} bytes")
135
+ """
136
+ if header_parser is None:
137
+ # Default: 2-byte big-endian length prefix
138
+ header_parser = BinaryParser(">H")
139
+ length_field = 0
140
+
141
+ header_size = header_parser.size
142
+
143
+ if isinstance(file_or_buffer, bytes):
144
+ buffer: BinaryIO = io.BytesIO(file_or_buffer)
145
+ should_close = True
146
+ elif isinstance(file_or_buffer, str | Path):
147
+ buffer = open(file_or_buffer, "rb") # noqa: SIM115
148
+ should_close = True
149
+ else:
150
+ buffer = file_or_buffer
151
+ should_close = False
152
+
153
+ try:
154
+ packet_num = 0
155
+
156
+ while True:
157
+ # Read header
158
+ header_bytes = buffer.read(header_size)
159
+ if len(header_bytes) < header_size:
160
+ break
161
+
162
+ header = header_parser.unpack(header_bytes)
163
+ length = header[length_field]
164
+
165
+ # Compute payload size
166
+ payload_size = length - header_size if header_included else length
167
+
168
+ if payload_size < 0:
169
+ break
170
+
171
+ # Read payload
172
+ payload = buffer.read(payload_size)
173
+ if len(payload) < payload_size:
174
+ break
175
+
176
+ packet_num += 1
177
+
178
+ yield StreamPacket(
179
+ timestamp=packet_num, # Placeholder
180
+ data=header_bytes + payload,
181
+ metadata={"header": header, "packet_num": packet_num},
182
+ )
183
+
184
+ finally:
185
+ if should_close:
186
+ buffer.close()
187
+
188
+
189
+ def stream_delimited(
190
+ file_or_buffer: str | Path | BinaryIO | bytes,
191
+ delimiter: bytes = b"\n",
192
+ *,
193
+ max_record_size: int = 1048576,
194
+ ) -> Iterator[bytes]:
195
+ """Stream delimiter-separated records.
196
+
197
+ Args:
198
+ file_or_buffer: Source.
199
+ delimiter: Record delimiter (default newline).
200
+ max_record_size: Maximum record size (default 1MB).
201
+
202
+ Yields:
203
+ Records as bytes (without delimiter).
204
+
205
+ Example:
206
+ >>> for line in stream_delimited("log.txt", b"\\n"):
207
+ ... process_line(line)
208
+ """
209
+ if isinstance(file_or_buffer, bytes):
210
+ buffer: BinaryIO = io.BytesIO(file_or_buffer)
211
+ should_close = True
212
+ elif isinstance(file_or_buffer, str | Path):
213
+ buffer = open(file_or_buffer, "rb") # noqa: SIM115
214
+ should_close = True
215
+ else:
216
+ buffer = file_or_buffer
217
+ should_close = False
218
+
219
+ try:
220
+ partial = b""
221
+
222
+ while True:
223
+ chunk = buffer.read(65536)
224
+ if not chunk:
225
+ if partial:
226
+ yield partial
227
+ break
228
+
229
+ data = partial + chunk
230
+ parts = data.split(delimiter)
231
+
232
+ # Yield complete records
233
+ for part in parts[:-1]:
234
+ if len(part) <= max_record_size:
235
+ yield part
236
+
237
+ # Keep partial record for next iteration
238
+ partial = parts[-1]
239
+
240
+ # Guard against memory issues
241
+ if len(partial) > max_record_size:
242
+ yield partial[:max_record_size]
243
+ partial = b""
244
+
245
+ finally:
246
+ if should_close:
247
+ buffer.close()
248
+
249
+
250
+ def pipeline(
251
+ source: Iterator[T],
252
+ *transforms: Callable[[Iterator[T]], Iterator[T]],
253
+ ) -> Iterator[T]:
254
+ """Chain processing transforms.
255
+
256
+ Args:
257
+ source: Source iterator.
258
+ *transforms: Transform functions.
259
+
260
+ Yields:
261
+ Transformed items.
262
+
263
+ Example:
264
+ >>> def filter_large(packets):
265
+ ... for pkt in packets:
266
+ ... if len(pkt.data) > 100:
267
+ ... yield pkt
268
+ ...
269
+ >>> def decode(packets):
270
+ ... for pkt in packets:
271
+ ... pkt.metadata["decoded"] = decode_packet(pkt.data)
272
+ ... yield pkt
273
+ ...
274
+ >>> for pkt in pipeline(stream_packets(f), filter_large, decode):
275
+ ... print(pkt)
276
+ """
277
+ result: Iterator = source # type: ignore[type-arg]
278
+
279
+ for transform in transforms:
280
+ result = transform(result)
281
+
282
+ yield from result
283
+
284
+
285
+ def batch[T](
286
+ source: Iterator[T],
287
+ size: int,
288
+ ) -> Iterator[list[T]]:
289
+ """Batch items from iterator.
290
+
291
+ Args:
292
+ source: Source iterator.
293
+ size: Batch size.
294
+
295
+ Yields:
296
+ Lists of items.
297
+
298
+ Example:
299
+ >>> for batch_items in batch(stream_packets(f), size=100):
300
+ ... process_batch(batch_items)
301
+ """
302
+ current_batch: list[T] = []
303
+
304
+ for item in source:
305
+ current_batch.append(item)
306
+ if len(current_batch) >= size:
307
+ yield current_batch
308
+ current_batch = []
309
+
310
+ if current_batch:
311
+ yield current_batch
312
+
313
+
314
+ def take[T](source: Iterator[T], n: int) -> Iterator[T]:
315
+ """Take first n items.
316
+
317
+ Args:
318
+ source: Source iterator.
319
+ n: Number of items to take.
320
+
321
+ Yields:
322
+ First n items.
323
+ """
324
+ count = 0
325
+ for item in source:
326
+ if count >= n:
327
+ break
328
+ yield item
329
+ count += 1 # noqa: SIM113
330
+
331
+
332
+ def skip[T](source: Iterator[T], n: int) -> Iterator[T]:
333
+ """Skip first n items.
334
+
335
+ Args:
336
+ source: Source iterator.
337
+ n: Number of items to skip.
338
+
339
+ Yields:
340
+ Items after first n.
341
+ """
342
+ count = 0
343
+ for item in source:
344
+ if count >= n:
345
+ yield item
346
+ count += 1 # noqa: SIM113
347
+
348
+
349
+ __all__ = [
350
+ "StreamPacket",
351
+ "batch",
352
+ "pipeline",
353
+ "skip",
354
+ "stream_delimited",
355
+ "stream_file",
356
+ "stream_packets",
357
+ "stream_records",
358
+ "take",
359
+ ]
@@ -0,0 +1,266 @@
1
+ """Pattern Detection & Analysis module for Oscura.
2
+
3
+ This module provides comprehensive pattern detection and analysis capabilities
4
+ for digital signals and binary data, including:
5
+
6
+ - Periodic pattern detection (autocorrelation, FFT, suffix array)
7
+ - Repeating sequence detection (n-grams, LRS, approximate matching)
8
+ - Automatic signature discovery (headers, delimiters, magic bytes)
9
+ - Pattern clustering by similarity (Hamming, edit distance, hierarchical)
10
+ - Binary regex pattern matching
11
+ - Multi-pattern search (Aho-Corasick)
12
+ - Fuzzy/approximate pattern matching
13
+ - Pattern learning and discovery
14
+
15
+ - RE-PAT-001: Binary Regex Pattern Matching
16
+ - RE-PAT-002: Multi-Pattern Search (Aho-Corasick)
17
+ - RE-PAT-003: Fuzzy Pattern Matching
18
+ - RE-PAT-004: Pattern Learning and Discovery
19
+
20
+ Author: Oscura Development Team
21
+ """
22
+
23
+ # Periodic pattern detection (PAT-001)
24
+ # Pattern clustering (PAT-004)
25
+ from .clustering import (
26
+ ClusteringResult,
27
+ ClusterResult,
28
+ analyze_cluster,
29
+ cluster_by_edit_distance,
30
+ cluster_by_hamming,
31
+ cluster_hierarchical,
32
+ compute_distance_matrix,
33
+ )
34
+
35
+ # Signature discovery (PAT-003)
36
+ from .discovery import (
37
+ CandidateSignature,
38
+ SignatureDiscovery,
39
+ discover_signatures,
40
+ find_delimiter_candidates,
41
+ find_header_candidates,
42
+ )
43
+
44
+ # RE-PAT-004: Pattern Learning and Discovery
45
+ from .learning import (
46
+ LearnedPattern,
47
+ NgramModel,
48
+ PatternLearner,
49
+ StructureHypothesis,
50
+ find_recurring_structures,
51
+ infer_structure,
52
+ learn_patterns_from_data,
53
+ )
54
+
55
+ # RE-PAT-001, RE-PAT-002, RE-PAT-003: Advanced pattern matching
56
+ from .matching import (
57
+ AhoCorasickMatcher,
58
+ # Classes
59
+ BinaryRegex,
60
+ FuzzyMatcher,
61
+ FuzzyMatchResult,
62
+ # Data classes
63
+ PatternMatchResult,
64
+ # RE-PAT-001: Binary Regex
65
+ binary_regex_search,
66
+ count_pattern_occurrences,
67
+ # Utilities
68
+ find_pattern_positions,
69
+ find_similar_sequences,
70
+ # RE-PAT-003: Fuzzy Matching
71
+ fuzzy_search,
72
+ # RE-PAT-002: Multi-Pattern Search
73
+ multi_pattern_search,
74
+ )
75
+ from .periodic import (
76
+ PeriodicPatternDetector,
77
+ PeriodResult,
78
+ detect_period,
79
+ detect_periods_autocorr,
80
+ detect_periods_fft,
81
+ validate_period,
82
+ )
83
+
84
+ # Alias for backward compatibility
85
+ detect_period_autocorr = detect_periods_autocorr
86
+ detect_period_fft = detect_periods_fft
87
+
88
+ # Repeating sequence detection (PAT-002)
89
+ # Motif detection functions (aliases for test compatibility)
90
+ from typing import TYPE_CHECKING, Any, cast
91
+
92
+ from .sequences import (
93
+ NgramResult,
94
+ RepeatingSequence,
95
+ find_approximate_repeats,
96
+ find_frequent_ngrams,
97
+ find_longest_repeat,
98
+ find_repeating_sequences,
99
+ )
100
+
101
+ if TYPE_CHECKING:
102
+ import numpy as np
103
+ from numpy.typing import NDArray
104
+
105
+
106
+ def find_motifs(
107
+ data: Any, motif_length: int = 8, max_distance: float = 0.1
108
+ ) -> list[RepeatingSequence]:
109
+ """Find motifs (repeating patterns) in data.
110
+
111
+ This is an alias for find_repeating_sequences for test compatibility.
112
+
113
+ Args:
114
+ data: Input data array.
115
+ motif_length: Length of motifs to find.
116
+ max_distance: Maximum distance for fuzzy matching (unused).
117
+
118
+ Returns:
119
+ List of RepeatingSequence objects.
120
+ """
121
+ import numpy as np
122
+
123
+ data = np.asarray(data)
124
+ results = find_repeating_sequences(data, min_length=motif_length, min_count=2)
125
+ return results
126
+
127
+
128
+ def extract_motif(data: Any, start: int, length: int) -> "NDArray[np.generic]":
129
+ """Extract a motif from data.
130
+
131
+ Args:
132
+ data: Input data array.
133
+ start: Start index.
134
+ length: Length to extract.
135
+
136
+ Returns:
137
+ Extracted motif as numpy array.
138
+ """
139
+ import numpy as np
140
+ from numpy.typing import NDArray
141
+
142
+ data_arr = np.asarray(data)
143
+ result: NDArray[np.generic] = data_arr[start : start + length]
144
+ return result
145
+
146
+
147
+ def detect_anomalies(data: Any, threshold: float = 3.0) -> list[int]:
148
+ """Detect anomalies in data using z-score.
149
+
150
+ Args:
151
+ data: Input data array.
152
+ threshold: Z-score threshold for anomaly detection.
153
+
154
+ Returns:
155
+ List of anomaly indices.
156
+ """
157
+ import numpy as np
158
+
159
+ data_arr = np.asarray(data)
160
+ mean = np.mean(data_arr)
161
+ std = np.std(data_arr)
162
+ if std == 0:
163
+ return []
164
+
165
+ z_scores = np.abs((data_arr - mean) / std)
166
+ indices = np.where(z_scores > threshold)[0].tolist()
167
+ return cast("list[int]", indices)
168
+
169
+
170
+ def cluster_patterns(patterns: Any, method: str = "hamming") -> ClusteringResult:
171
+ """Cluster patterns by similarity.
172
+
173
+ Args:
174
+ patterns: List of patterns to cluster.
175
+ method: Clustering method ('hamming' or 'edit').
176
+
177
+ Returns:
178
+ ClusteringResult with cluster assignments.
179
+ """
180
+ if method == "hamming":
181
+ return cluster_by_hamming(patterns)
182
+ else:
183
+ return cluster_by_edit_distance(patterns)
184
+
185
+
186
+ def pattern_similarity(pattern1: Any, pattern2: Any) -> float:
187
+ """Calculate similarity between two patterns.
188
+
189
+ Args:
190
+ pattern1: First pattern.
191
+ pattern2: Second pattern.
192
+
193
+ Returns:
194
+ Similarity score (0-1, 1 = identical).
195
+ """
196
+ import numpy as np
197
+
198
+ p1 = np.asarray(pattern1)
199
+ p2 = np.asarray(pattern2)
200
+
201
+ if len(p1) != len(p2):
202
+ return 0.0
203
+
204
+ if len(p1) == 0:
205
+ return 1.0
206
+
207
+ matches = int(np.sum(p1 == p2))
208
+ return float(matches / len(p1))
209
+
210
+
211
+ __all__ = [
212
+ # RE-PAT-002: Multi-Pattern Search
213
+ "AhoCorasickMatcher",
214
+ # RE-PAT-001: Binary Regex Pattern Matching
215
+ "BinaryRegex",
216
+ "CandidateSignature",
217
+ "ClusterResult",
218
+ "ClusteringResult",
219
+ "FuzzyMatchResult",
220
+ # RE-PAT-003: Fuzzy Pattern Matching
221
+ "FuzzyMatcher",
222
+ # RE-PAT-004: Pattern Learning and Discovery
223
+ "LearnedPattern",
224
+ "NgramModel",
225
+ "NgramResult",
226
+ "PatternLearner",
227
+ "PatternMatchResult",
228
+ "PeriodResult",
229
+ "PeriodicPatternDetector",
230
+ "RepeatingSequence",
231
+ "SignatureDiscovery",
232
+ "StructureHypothesis",
233
+ "analyze_cluster",
234
+ "binary_regex_search",
235
+ "cluster_by_edit_distance",
236
+ "cluster_by_hamming",
237
+ "cluster_hierarchical",
238
+ "cluster_patterns",
239
+ "compute_distance_matrix",
240
+ "count_pattern_occurrences",
241
+ # Motif detection (compatibility)
242
+ "detect_anomalies",
243
+ "detect_period",
244
+ "detect_period_autocorr",
245
+ "detect_period_fft",
246
+ "detect_periods_autocorr",
247
+ "detect_periods_fft",
248
+ "discover_signatures",
249
+ "extract_motif",
250
+ "find_approximate_repeats",
251
+ "find_delimiter_candidates",
252
+ "find_frequent_ngrams",
253
+ "find_header_candidates",
254
+ "find_longest_repeat",
255
+ "find_motifs",
256
+ "find_pattern_positions",
257
+ "find_recurring_structures",
258
+ "find_repeating_sequences",
259
+ "find_similar_sequences",
260
+ "fuzzy_search",
261
+ "infer_structure",
262
+ "learn_patterns_from_data",
263
+ "multi_pattern_search",
264
+ "pattern_similarity",
265
+ "validate_period",
266
+ ]