ASCII Art Image
ASCII Art Image
Platform: hackerlab | Category: Steganography | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2025-12-22 | Status: Solved Techniques: ASCII art to image conversion, Character-to-brightness mapping, Image rotation for text recovery
Summary
Task: Text file with ASCII art characters representing brightness levels. Solution: Convert characters to grayscale pixels using brightness mapping and rotate 180 degrees to reveal the flag.
ASCII Art Image — hackerlab.pro
Description
"Иногда мы не видим всей полноты картины..."
Task: a1e6e8a9-0ea3-4605-880e-c7cf528d2980
Analysis
- File file.txt — text file with dimensions 400x141 characters
- Content — characters
@#BG&P5Y7J?!~^:.— standard ASCII art palette - Principle — each character represents different brightness:
@— darkest (most "ink").— lightest (minimal "ink")- Intermediate characters — grayscale gradations
Solution
Step 1: Understanding ASCII Art Palette
ASCII art uses characters with different "density" to represent brightness:
- Characters with more pixels (
@,#,B) appear darker - Characters with fewer pixels (
.,:,^) appear lighter
Step 2: Converting to Image
python read-only • copy allowed#!/usr/bin/env python3 from PIL import Image import numpy as np # Read ASCII art with open('file.txt', 'r') as f: lines = [line.rstrip('\n') for line in f.readlines()] # ASCII art palette from dark to light ascii_order = "@#BG&P5Y7J?!~^:." char_to_brightness = {c: int(255 * i / (len(ascii_order) - 1)) for i, c in enumerate(ascii_order)} # Create image array height = len(lines) width = max(len(line) for line in lines) img_array = np.zeros((height, width), dtype=np.uint8) # Fill pixels for y, line in enumerate(lines): for x, char in enumerate(line): img_array[y, x] = char_to_brightness.get(char, 255) # Rotate 180 degrees (text was upside down) img_array = np.rot90(img_array, 2) # Save img = Image.fromarray(img_array) img.save('output.png')
Step 3: Improving Readability (Optional)
python read-only • copy allowed# Binarization for better contrast threshold = 128 binary = np.where(img_array > threshold, 255, 0).astype(np.uint8) Image.fromarray(binary).save('output_binary.png')
Step 4: Reading the Flag
After conversion and rotation, the flag text is readable on the image.
Important: Note the digit 1 instead of letter I in the word FR1END.
Standard ASCII Art Palettes
Short (10 characters): @%#*+=-:.
Medium (16 characters): @#BG&P5Y7J?!~^:.
Long (70 characters): $@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,"^`'.
Alternative Approaches
- Palette inversion — if image is negative, reverse the character order
- Different rotations — try 90°, 180°, 270°
- Mirroring — horizontal or vertical
- Scaling — ASCII art may be stretched along one axis