1043 грамма PLA
1043 грамма PLA
Platform: bug-makers | Category: Forensics | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2026-05-29 | Status: Solved Techniques: gcode_extrusion_parsing, layer_anomaly_detection, midpoint_layer_localization, toolpath_rendering
Summary
Task: a ~10MB Prusa i3 G-code file; a flag appears ~15h into a ~30.8h print, stays visible 30 min, then is overprinted. Solution: parse per-layer E-positive extrusion segments, detect the mid-print layer with an anomalous segment-count spike (the embedded text), and render those toolpaths top-down to read the flag.
1043 грамма PLA — bug-makers
Description
1043 грамма PLA. Примерно через 15 часов работы Prusa i3 появится флаг, и будет виден пол часа, потом исчезнет.
English: "1043 grams of PLA. After approximately 15 hours of Prusa i3 operation, a flag will appear, be visible for half an hour, then disappear."
Provided artifact: 1043.gcode.zip containing a single ~10 MB 1043.gcode file. The goal is to recover the flag that is only momentarily visible during the physical print.
Analysis
The G-code header from Cura tells us everything we need:
;FLAVOR:Marlin
;TIME:111086
;Filament used: 349.606m
;Layer height: 0.4
;MINX:12.2 ;MINY:12.2 ;MINZ:0.3 ;MAXX:187.8 ;MAXY:187.8 ;MAXZ:159.9
;TARGET_MACHINE.NAME:Prusa i3
;Generated with Cura_SteamEngine 5.11.0
;LAYER_COUNT:400
Semantic clue mapping. ;TIME:111086 seconds ≈ 30.86 hours is the full print time. The hint says the flag appears at ~15 hours — almost exactly half the print. With 400 layers, halfway corresponds to layer ~200. The phrasing "visible for half an hour, then disappears" is the key insight: the flag is printed as a thin text band at a mid-height layer, then buried (overprinted) by the subsequent solid layers. It is therefore invisible in the finished model and visible only mid-print. This is geometry steganography — the message lives in the toolpaths, not in any file metadata.
So the flag is not in the file's text/comments; it is in the extrusion geometry of a few layers around layer 200.
Solution
-
Parse extrusion segments per layer. In Marlin/Cura G-code, material is deposited only when the extruder axis
Eadvances. Track absoluteX/Y/E; aG0/G1move that increasesEis a printed segment(x0,y0,x1,y1). Layers are delimited by;LAYER:comments. -
Detect the anomalous layer via segment count. A normal layer of this model deposits ~382 segments (median). Detailed text glyphs require far more, short, segments, so the text layers stand out as a sharp spike:
Layer Segments median ~382 200 2129 201 2815 202 2579 203 2578 204 2582 205 2808 206 1250 Minor spikes at layers 1, 7–8, 394–395 are skirt and top/bottom solid fill — not text. The cluster at 200–206, exactly at the predicted midpoint, is the embedded text.
-
Render the anomalous layers top-down. Plot every extrusion segment of layers 200–206 in the XY plane with matplotlib. The first render (with an inverted Y axis, as many printers/plotters default to) showed the text mirrored. Removing the Y inversion and cropping to the text band (raw model coords Y ≈ 90–115, X ≈ 15–185) made the flag cleanly readable.
The toolpaths spell out the flag.
Reusable snippet — parse G-code extrusion + find anomalous layers
python read-only • copy allowed#!/usr/bin/env python3 # Parse Cura/Marlin G-code into per-layer extrusion segments, # flag layers whose segment count is an outlier (hidden geometry), # and render the suspect layers top-down to read embedded text. import re, statistics import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt def parse_layers(path): layers = [] # list of list-of-segments; segment = (x0,y0,x1,y1) cur = [] x = y = e = 0.0 abs_e = True # M82 = absolute extrusion (Cura default) for line in open(path, errors="ignore"): s = line.strip() if s.startswith(";LAYER:"): if cur: layers.append(cur) cur = [] continue if s.startswith("M83"): abs_e = False if s.startswith("M82"): abs_e = True if not (s.startswith("G0") or s.startswith("G1")): continue nx, ny, ne = x, y, None for tok in s.split(): if tok[0] == "X": nx = float(tok[1:]) elif tok[0] == "Y": ny = float(tok[1:]) elif tok[0] == "E": ne = float(tok[1:]) extruding = False if ne is not None: de = (ne - e) if abs_e else ne extruding = de > 1e-6 e = ne if abs_e else e + ne if extruding and (nx != x or ny != y): cur.append((x, y, nx, ny)) x, y = nx, ny if cur: layers.append(cur) return layers def anomalous_layers(layers, factor=2.5): counts = [len(l) for l in layers] med = statistics.median(counts) return [(i, c) for i, c in enumerate(counts) if c > factor * med], med def render(layers, idxs, out="text.png"): fig, ax = plt.subplots(figsize=(20, 6)) for i in idxs: for (x0, y0, x1, y1) in layers[i]: ax.plot([x0, x1], [y0, y1], color="black", linewidth=0.5) ax.set_aspect("equal") # DO NOT invert Y — keep model orientation fig.savefig(out, dpi=150) layers = parse_layers("1043.gcode") anoms, med = anomalous_layers(layers) print("median segs/layer:", med) print("anomalous:", anoms) # -> layers ~200-206 spike to 2000-2800 render(layers, range(200, 207)) # crop Y~90-115, X~15-185 to read flag