← Back to Writeups
CUSTOMEasyCrypto

Гирлянда (Garland)

XESXOR9/2/20264 min read
#crypto#custom#easy#base-conversion-(decimal-to-ba#custom-emoji-substitution-reve#reverse-engineering-multi-stag#source-code-analysis-to-unders

Гирлянда (Garland)

Platform: CUSTOM | Category: Crypto | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: Base conversion (decimal to base-9 and back), Custom emoji substitution reversal, Reverse engineering multi-stage encoding, Source code analysis to understand encryption chain

Summary

Walkthrough of the CUSTOM Crypto Гирлянда (Garland). Task: Decrypt an emoji garland message with provided encryption source code. Solution: Reverse the multi-stage encoding chain (emoji → base-9 → ASCII → text) by analyzing the three Python scripts.

Description

Друг обещал украсить ёлку с помощью гирлянд и зашифровать определённое сообщение. Мы немного выпили, а сейчас я проснулся: друга нет, гирлянда есть. И какие-то исходники. Помоги расшифровать его шифр.

Files:

  • task_garland.zip contains:
    • text_to_ascii.py - converts text to ASCII codes
    • decimal_to_ninary.py - converts decimal numbers to base-9 (nonary system)
    • numbers_to_emoji.py - maps digits 0-8 to colored circle emojis
    • Гирлянда - encrypted message (garland of emojis) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Analysis

Step 1: Analyzing the Encryption Scripts

Three Python scripts form the encryption chain:

text_to_ascii.py:

python
# Converts each text character to its ASCII code
# 'A' -> 65, 'B' -> 66, etc.

decimal_to_ninary.py:

python
# Converts decimal number to base-9 (nonary) system
# 65 -> "72" (6*9 + 5 = 59... no, 7*9 + 2 = 65)

numbers_to_emoji.py:

python
# Mapping digits 0-8 to colored emojis:
emoji_map = {
    '0': '🟢',  # green
    '1': '🟣',  # purple
    '2': '⚫️',  # black
    '3': '🔴',  # red
    '4': '🟡',  # yellow
    '5': '🟠',  # orange
    '6': '🔵',  # blue
    '7': '⚪️',  # white
    '8': '🟤',  # brown
}

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Step 2: Understanding the Encryption Chain

Text → ASCII code → Base-9 → Emoji
  'C'  →    67     →  "74"  → "⚪️🟡"

Each text character:

  1. Is converted to ASCII code (ord())
  2. ASCII code is converted to base-9
  3. Each base-9 digit is replaced with the corresponding emoji

Characters are separated by spaces in the final message.

Step 3: The "Гирлянда" File

The file contains emoji sequences separated by spaces:

⚪️🟡 ⚪️🟢 ... (and so on)

Solution

Reverse decryption process:

python
#!/usr/bin/env python3
"""
Garland Decryption - Reverse the emoji -> base9 -> ASCII encoding
"""
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Reverse emoji mapping (emoji -> base-9 digit)
emoji_to_digit = {
    '🟢': '0',
    '🟣': '1',
    '⚫': '2',  # Note: may need to handle emoji variants
    '⚫️': '2',
    '🔴': '3',
    '🟡': '4',
    '🟡': '4',
    '🟠': '5',
    '🔵': '6',
    '⚪': '7',
    '⚪️': '7',
    '🟤': '8',
}

def emoji_to_base9(emoji_seq):
    """Convert emoji sequence to base-9 string"""
    result = ""
    for char in emoji_seq:
        if char in emoji_to_digit:
            result += emoji_to_digit[char]
    return result
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

def base9_to_decimal(base9_str):
    """Convert base-9 string to decimal integer"""
    result = 0
    for digit in base9_str:
        result = result * 9 + int(digit)
    return result

def decrypt_garland(encrypted_text):
    """Decrypt the garland message"""
    # Split by spaces to get individual character encodings
    emoji_groups = encrypted_text.strip().split(' ')
    
    decrypted = ""
    for group in emoji_groups:
        if not group:
            continue
        # Emoji -> Base-9 string
        base9_str = emoji_to_base9(group)
        if base9_str:
            # Base-9 -> Decimal (ASCII code)
            ascii_code = base9_to_decimal(base9_str)
            # ASCII code -> Character
            decrypted += chr(ascii_code)
    
    return decrypted
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# Read the encrypted garland file
with open('Гирлянда', 'r', encoding='utf-8') as f:
    encrypted = f.read()

# Decrypt
message = decrypt_garland(encrypted)
print(message)

Decrypted Message

The Codeby team congratulates all players of the Codeby Games platform on the upcoming New Year! Thank you very much for staying with us: we love and appreciate you very much! We hope that in the New Year 2025 we will be able to please you even more with tasks and tasks on the platform. Take your New Year's flag - CODEBY{REDACTED}. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Notes

  • The name "Гирлянда" (Garland) — reference to a New Year's garland of colorful lights
  • 9 emoji colors — hint at the base-9 (nonary) number system
  • "Ninary" in the filename — wordplay (nine + binary = ninary/nonary)
  • New Year theme of the task (2025 points, New Year congratulations) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering Base conversion (decimal to base-9 and back), Custom emoji substitution reversal, Reverse engineering multi-stage encoding, Source code analysis to understand encryption chain was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-01-02 • CUSTOM • Гирлянда (Garland) • Difficulty: Easy