← Back to Writeups
CUSTOMMediumMisc

Terminal Diff

XESXOR9/10/20264 min read
#misc#custom#medium#ascii_art_ocr_via_pixel_render#braille_image_recognition#directional_arrow_spiral_readi#factoring_character_count_to_t#figlet_ticks_font_recognition#text_wrapping_at_97_columns

Terminal Diff

Platform: CUSTOM | Category: Misc | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: ascii_art_ocr_via_pixel_render, braille_image_recognition, directional_arrow_spiral_reading, factoring_character_count_to_terminal_width, figlet_ticks_font_recognition, text_wrapping_at_97_columns

Summary

Walkthrough of the CUSTOM Misc Terminal Diff. Task: a single 3395-char Unicode line (flag.txt) whose riddle hints at a terminal size. Solution: factor the length (3395 = 5797), wrap at 97 columns to reveal FIGlet 'ticks' block letters around a

Description

I used to be too big picture, never focusing on the details (keeping track of like 90 things at once). Then, I starting looking into things a little bit too much (this phase only lasted like 7 days). Nowadays though, I am primed to look at things with just the right width (and height too). Anyways, here's the flag! You should be able to read it just fine, as long as you align with my mindset.

The only artifact is flag.txt from the CTFd instance: one very long single line of Unicode text. The riddle is a disguised hint about the correct terminal width (and height) at which the line should be wrapped so that the ASCII art becomes readable.

Analysis

file flag.txt reports "Unicode text, UTF-8, with very long lines". The file is a single line of 3395 characters (4140 bytes). The character set is small:

  • / \ _ < > ^ v — ASCII art strokes and directional markers
  • many codepoints in the Braille block (U+2800) — used to draw a small picture

The riddle encodes a terminal size through numeric decoys:

  • "keeping track of like 90 things" → width 90 is too big
  • "this phase only lasted like 7 days" → width 7 is too small
  • "just the right width (and height too)" + "align with my mindset" → wrap the single line at the correct terminal width

The clean way to find the width is to factor the character count:

3395 = 5 × 7 × 97

Wrapping the line every 97 characters yields exactly 35 rows (5 × 7). The intended terminal is 97 columns × 35 rows.

Solution

1. Factor the length and wrap

python
import sympy
s = open('flag.txt').read().rstrip('\n')
print(len(s), sympy.factorint(len(s)))   # 3395  {5:1, 7:1, 97:1}
w = 97
print('\n'.join(s[i:i+w] for i in range(0, len(s), w)))

Wrapped at 97 columns, the / and \ characters form large block letters — a narrow FIGlet "ticks"-style font (the standard figlet -f ticks uses /\/\ per stroke; this puzzle uses a half-width /\ variant). The _ characters are the font's background padding. The Braille block (U+2800) in the middle draws an oyster — a thematic nod to the idiom "the world is your oyster".

2. Render to pixels for OCR

Treat / and \ as filled pixels and everything else as background, then rasterize to a scaled PNG so the letters become legible:

python
from PIL import Image
rows = [s[i:i+97] for i in range(0, len(s), 97)]
scale = 9
img = Image.new('1', (97*scale, 35*scale), 1)
px = img.load()
for r in range(35):
    line = rows[r] if r < len(rows) else ''
    for c in range(97):
        if c < len(line) and line[c] in '/\\':
            for dy in range(scale):
                for dx in range(scale):
                    px[c*scale+dx, r*scale+dy] = 0
img.save('clean.png')

3. The letter grid

The glyphs are laid out in a 6×8 grid of FIGlet letters wrapping around the central oyster:

bronco{r
le_world
o      as     <- oyster image occupies the middle of these three lines
h      ti
w       z
_say_...

4. Directional arrows define reading order

Non-letter markers appear at the edges of the grid:

  • >> at the left of band le_world → read rightward
  • vvvv down the right side → read downward
  • << at the bottom-right → read leftward
  • ^^^^ up the left side → read upward

These trace a clockwise spiral around the oyster. Reading the grid naively in row-major order produces gibberish (bronco{rle_worldoashtiwz_say_...); the arrows are mandatory.

5. Decode the words

Verified glyph-by-glyph from the render:

  • Rightmost column top→bottom, continuing into the bottom-right corner = resizing (r-e-s-i-z-i-n-g)
  • Left column bottom→top, turning right into band le_world = whole_world (who + le + _world)
  • Bottom-middle = say (appears reversed as _yas_ because the spiral crosses the bottom right-to-left)

Assembling the spiral in natural reading order yields the sentence matching the riddle's theme — fitting "the whole world" into the terminal by resizing it:

bronco{REDACTED}

Key Takeaways / Lessons

  • Mastering ascii_art_ocr_via_pixel_render, braille_image_recognition, directional_arrow_spiral_reading, factoring_character_count_to_terminal_width, figlet_ticks_font_recognition, text_wrapping_at_97_columns was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-07-11 • CUSTOM • Terminal Diff • Difficulty: Medium