app
Adom Library
Public Made by Adomby adom
adom-lbr — the EDA library translator. Bring a component in from any supported EDA tool and convert it to any other (KiCad ⇄ Altium ⇄ EAGLE/Fusion) through one canonical adom-lbr JSON — symbol + footprint + 3D + pin↔pad map. Altium is written natively (no Altium needed). Includes the adom-lbr Manager: browse wiki components and view symbol/footprint/3D + the per-EDA layer stackup.
← Commit history
Altium model checksum: the position-weighted sum Altium validates (wiki #22)
2 files changed
+38−5
crates/altium-codec/src/lib.rs+19@@ -47,6 +47,25 @@ mod tests { } } + #[test]+ fn model_checksum_matches_altium_and_the_vendor_fixture() {+ // Tiny hand-computed case: [73, 2, 3] -> 73*1 + 2*1 + 3*2 = 81.+ assert_eq!(pcblib::altium_model_checksum(&[73, 2, 3]), 81);+ // The vendor fixture is a third independent ground truth: its stored+ // model checksum is 3227565272 (signed -1067402024) over the+ // decompressed STEP in Library/Models/0.+ let fixture = concat!(env!("CARGO_MANIFEST_DIR"), "/../altium-pcblib/tests/fixtures/ADS1220IRVAT.PcbLib");+ if let Ok(bytes) = std::fs::read(fixture) {+ use std::io::Read;+ let mut comp = cfb::CompoundFile::open(std::io::Cursor::new(bytes)).unwrap();+ let mut raw = Vec::new();+ comp.open_stream("/Library/Models/0").unwrap().read_to_end(&mut raw).unwrap();+ let mut dec = Vec::new();+ flate2::read::ZlibDecoder::new(&raw[..]).read_to_end(&mut dec).unwrap();+ assert_eq!(pcblib::altium_model_checksum(&dec), 3227565272u32);+ }+ }+ #[test] fn overall_height_comes_from_the_step_z_extent() { // 1.2 mm of z-extent must render as Altium writes it: 47.2441mil
crates/altium-codec/src/pcblib.rs+19−5@@ -206,11 +206,7 @@ pub fn encode_pcblib_many_with_models(fps: &[Footprint], models: &[Option<Embedd for m in models { match m { Some(em) => {- let checksum = {- let mut h = flate2::Crc::new();- h.update(&em.step);- h.sum()- };+ let checksum = altium_model_checksum(&em.step); let guid = model_guid(&em.name, &em.step); let height_mil = if em.overall_height_mil > 0.0 { em.overall_height_mil@@ -607,6 +603,24 @@ fn harvest_pad_data_block(tpl: &BTreeMap<String, Vec<u8>>) -> Result<Vec<u8>> { } /// Create any missing parent storages, then write `path` as a stream.+/// Altium's model checksum over the DECOMPRESSED STEP bytes: byte 0 weighted+/// by 1, every later byte weighted by its offset, summed mod 2^32. Cracked by+/// feeding Altium's own model factory four controlled single-byte variants+/// and reading back the checksums it computed (adom-lbr#22); the deltas were+/// linear and position-weighted. Verified exact against three independent+/// ground-truth files (two oracle captures plus the ADS1220IRVAT vendor+/// fixture). Altium validates this on load and CULLS the mesh on mismatch,+/// so a wrong value renders bare pads. The store record prints it signed,+/// the body record unsigned; both are this one u32. (Byte 0's weight of 1 is+/// indistinguishable from a +73 constant, since every STEP starts with "I".)+pub fn altium_model_checksum(step: &[u8]) -> u32 {+ let mut sum: u32 = step.first().map(|b| *b as u32).unwrap_or(0);+ for (i, b) in step.iter().enumerate().skip(1) {+ sum = sum.wrapping_add((i as u32).wrapping_mul(*b as u32));+ }+ sum+}+ /// Overall height of a STEP body in mils, from the z-extent of its /// CARTESIAN_POINT entities (wiki part models are millimetre-unit STEP). /// Altium CULLS a body whose OVERALLHEIGHT is 0, so this is what keeps an