← Back to Writeups
CUSTOMEasyMisc

Louis Braille

XESXOR9/2/20266 min read
#misc#custom#easy#braille_decoding#ueb_braille_analysis

Louis Braille

Platform: taipanbyte | Category: Misc | Type: Challenge | Difficulty: Easy | OS: NA | Author: XESXOR | Date: 2026-02-14 | Status: Solved Techniques: braille_decoding, ueb_braille_analysis

Summary

Task: Decode Unicode Braille characters from challenge description. Solution: Parse UEB (Unified English Braille) with proper handling of indicators for numbers, capitals, and special characters like underscore.

Louis Braille — TaipanByte

Description

The challenge is named after Louis Braille — the inventor of the Braille alphabet. The description contains a string of Unicode Braille characters:

⠠⠠⠞⠃⠸⠣⠼⠁⠨⠤⠙⠼⠚⠝⠞⠨⠤⠎⠼⠉⠉⠨⠤⠠⠁⠝⠽⠨⠤⠏⠗⠼⠚⠰⠃⠇⠼⠉⠍⠎⠸⠜

Files: none. The flag is encoded directly in the challenge description.

Analysis

The task is to decode text from UEB (Unified English Braille). Key observations:

  1. Name "Louis Braille" — direct hint at Braille alphabet
  2. Unicode Braille — characters from the U+2800–U+28FF range, each representing a combination of 6 or 8 dots
  3. UEB (Unified English Braille) — a standard that uses indicators to switch modes (numbers, capital letters, special characters)
  4. Trap: the symbol ⠨⠤ (dots 46 + dots 36) is underscore _, NOT hyphen -. A single ⠤ (dots 36) is hyphen. The prefix ⠨ (dot 46) changes the meaning. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Solution

Key UEB Indicators

SymbolDotsMeaning
⠠dot 6Capital letter (next letter is uppercase)
⠠⠠dot 6 × 2Caps word (entire word in uppercase)
⠼dots 3456Number indicator (following characters are digits)
⠰dots 56Grade 1 indicator (return to letters from number mode)
⠨⠤dots 46 + 36Underscore _
⠸⠣dots 456 + 126Opening brace {
⠸⠜dots 456 + 345Closing brace }

Step-by-Step Decoding

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

BrailleValueNote
⠠⠠CAPS WORDNext word in uppercase
⠞⠃TBt=⠞, b=⠃ (uppercase due to ⠠⠠)
⠸⠣{Opening curly brace (terminates caps word)
⠼⠁1⠼ = number, ⠁ = a = 1
⠨⠤_Underscore
⠙dLetter (number mode terminated)
⠼⠚0⠼ = number, ⠚ = j = 0
⠝⠞ntLetters (number mode terminated)
⠨⠤_Underscore
⠎sLetter
⠼⠉⠉33⠼ = number, ⠉ = c = 3, ⠉ = c = 3
⠨⠤_Underscore
⠠⠁A⠠ = capital, ⠁ = a
⠝⠽nyLetters
⠨⠤_Underscore
⠏⠗prLetters
⠼⠚0⠼ = number, ⠚ = j = 0
⠰⠃b⠰ = grade 1 indicator (exit number mode), ⠃ = b
⠇lLetter
⠼⠉3⠼ = number, ⠉ = c = 3
⠍⠎msLetters (number mode terminated)
⠸⠜}Closing curly brace
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Result: TB{REDACTED} — leet-speak for "I don't see Any problems"

Python Script for Decoding

python
#!/usr/bin/env python3
"""UEB Braille decoder for TaipanByte Louis Braille challenge."""

# UEB Braille letter mappings (dots -> letter)
BRAILLE_LETTERS = {
    '⠁': 'a', '⠃': 'b', '⠉': 'c', '⠙': 'd', '⠑': 'e',
    '⠋': 'f', '⠛': 'g', '⠓': 'h', '⠊': 'i', '⠚': 'j',
    '⠅': 'k', '⠇': 'l', '⠍': 'm', '⠝': 'n', '⠕': 'o',
    '⠏': 'p', '⠟': 'q', '⠗': 'r', '⠎': 's', '⠞': 't',
    '⠥': 'u', '⠧': 'v', '⠺': 'w', '⠭': 'x', '⠽': 'y',
    '⠵': 'z',
}
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

# In number mode, same cells map to digits
BRAILLE_DIGITS = {
    '⠁': '1', '⠃': '2', '⠉': '3', '⠙': '4', '⠑': '5',
    '⠋': '6', '⠛': '7', '⠓': '8', '⠊': '9', '⠚': '0',
}

def decode_ueb(braille_str):
    chars = list(braille_str)
    result = []
    i = 0
    number_mode = False
    caps_word = False
    cap_next = False

    while i < len(chars):
        c = chars[i]

        # Caps word indicator ⠠⠠
        if c == '⠠' and i + 1 < len(chars) and chars[i + 1] == '⠠':
            caps_word = True
            i += 2
            continue
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

        # Single capital indicator ⠠
        if c == '⠠':
            cap_next = True
            i += 1
            continue

        # Number indicator ⠼
        if c == '⠼':
            number_mode = True
            i += 1
            continue

        # Grade 1 indicator ⠰ (exits number mode)
        if c == '⠰':
            number_mode = False
            i += 1
            continue

        # Opening brace ⠸⠣
        if c == '⠸' and i + 1 < len(chars) and chars[i + 1] == '⠣':
            result.append('{')
            caps_word = False  # Brace terminates caps word
            i += 2
            continue
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

        # Closing brace ⠸⠜
        if c == '⠸' and i + 1 < len(chars) and chars[i + 1] == '⠜':
            result.append('}')
            i += 2
            continue

        # Underscore ⠨⠤ (NOT hyphen!)
        if c == '⠨' and i + 1 < len(chars) and chars[i + 1] == '⠤':
            result.append('_')
            number_mode = False
            i += 2
            continue

        # Letter or digit
        if c in BRAILLE_LETTERS:
            if number_mode:
                if c in BRAILLE_DIGITS:
                    result.append(BRAILLE_DIGITS[c])
                else:
                    # Letter encountered in number mode -> exit number mode
                    number_mode = False
                    letter = BRAILLE_LETTERS[c]
                    if cap_next or caps_word:
                        letter = letter.upper()
                        cap_next = False
                    result.append(letter)
            else:
                letter = BRAILLE_LETTERS[c]
                if cap_next or caps_word:
                    letter = letter.upper()
                    cap_next = False
                result.append(letter)
            continue
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

        i += 1

    return ''.join(result)


braille_input = "⠠⠠⠞⠃⠸⠣⠼⠁⠨⠤⠙⠼⠚⠝⠞⠨⠤⠎⠼⠉⠉⠨⠤⠠⠁⠝⠽⠨⠤⠏⠗⠼⠚⠰⠃⠇⠼⠉⠍⠎⠸⠜"
flag = decode_ueb(braille_input)
print(f"Flag: {flag}")

Output:

Flag: TB{REDACTED}

Common Mistakes

  1. ⠨⠤ vs ⠤: The most common mistake is confusing underscore (⠨⠤, dots 46+36) with hyphen (⠤, dots 36). The prefix ⠨ (dot 46) critically changes the meaning.
  2. Number mode: After ⠼ all letter cells are read as digits until a letter without a digit value is encountered, or the special indicator ⠰.
  3. Caps word vs single cap: ⠠⠠ capitalizes the entire word, ⠠ — only the next letter. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Reference: UEB Braille

Letters (dots)

a ⠁ (1)      n ⠝ (1345)
b ⠃ (12)     o ⠕ (135)
c ⠉ (14)     p ⠏ (1234)
d ⠙ (145)    q ⠟ (12345)
e ⠑ (15)     r ⠗ (1235)
f ⠋ (124)    s ⠎ (234)
g ⠛ (1245)   t ⠞ (2345)
h ⠓ (125)    u ⠥ (136)
i ⠊ (24)     v ⠧ (1236)
j ⠚ (245)    w ⠺ (2456)
k ⠅ (13)     x ⠭ (1346)
l ⠇ (123)    y ⠽ (13456)
m ⠍ (134)    z ⠵ (1356)

Digits (after ⠼)

1=⠁  2=⠃  3=⠉  4=⠙  5=⠑
6=⠋  7=⠛  8=⠓  9=⠊  0=⠚

Indicators

⠠     Capital next letter
⠠⠠    Capital word
⠼     Number mode
⠰     Grade 1 (letter mode)
⠸⠣    { (opening brace)
⠸⠜    } (closing brace)
⠨⠤    _ (underscore)
⠤     - (hyphen)

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

Related Techniques

  • Morse code — dots and dashes (. and -)
  • Semaphore — visual encoding with flags
  • ASCII art / Tap code — other tactile/visual encodings
  • Leet speak — replacing letters with digits (1=I, 0=O, 3=E) ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍