← Back to Writeups
CUSTOMEasySteganography

Dvorak Cipher

XESXOR9/2/20262 min read
#steganography#custom#easy#character-substitution-cipher-#dvorak-to-qwerty-keyboard-layo

Dvorak Cipher

Platform: hackerlab | Category: Steganography | Type: Challenge | Difficulty: Easy | OS: NA | Author: XESXOR | Date: 2025-12-22 | Status: Solved Techniques: Character substitution cipher decoding, DVORAK to QWERTY keyboard layout mapping

Summary

Task: Decode ciphertext that looks like random characters with numbers unchanged. Solution: Recognize DVORAK to QWERTY keyboard layout cipher and map characters between layouts.

Dvorak Cipher — hackerlab.pro

Description

Криптография в категории стеганографии? Или это не шифр?

Given ciphertext:

JRE>XF?e1e{f0g{ydcbt{1y{,ao{4{j0e.Z+

Analysis

The hint in the task description: "Or is this not a cipher?" suggests this is not classical cryptography.

Key observations:

  1. Numbers stay in place — 1, 0, 4 are unchanged
  2. Strange symbols — >, ?, {, ,, ., + in unexpected places
  3. Some letters look like parts of words but don't form meaningful text ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

These are characteristic signs of a keyboard layout cipher — when text is typed on one keyboard layout, but the system interprets keystrokes as another layout.

DVORAK vs QWERTY

DVORAK is an alternative keyboard layout designed for more efficient typing:

QWERTY: `1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./
DVORAK: `1234567890[]",.pyfgcrl/=aoeuidhtns-;qjkxbmwvz

If someone types text thinking they have DVORAK, but the system uses QWERTY — you get a "cipher".

Solution

python
#!/usr/bin/env python3
"""
DVORAK to QWERTY keyboard cipher decoder
"""
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

# Lowercase mappings
dvorak_chars = "`1234567890[]\",.pyfgcrl/=aoeuidhtns-;qjkxbmwvz"
qwerty_chars = "`1234567890-=qwertyuiop[]asdfghjkl;'zxcvbnm,./"

dvorak_to_qwerty = {}
for d, q in zip(dvorak_chars, qwerty_chars):
    dvorak_to_qwerty[d] = q

# Uppercase mappings
dvorak_chars_upper = "~!@#$%^&*(){}\"<>PYFGCRL?+AOEUIDHTNS_;QJKXBMWVZ"
qwerty_chars_upper = "~!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?"
for d, q in zip(dvorak_chars_upper, qwerty_chars_upper):
    dvorak_to_qwerty[d] = q

# Decode
cipher = "JRE>XF?e1e{f0g{ydcbt{1y{,ao{4{j0e.Z+"
flag = ''.join(dvorak_to_qwerty.get(c, c) for c in cipher)
print(flag)

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

Output:

CODEBY{REDACTED}

Other keyboard layout ciphers

Similar techniques exist for other layouts:

  • AZERTY (French) ↔ QWERTY
  • QWERTZ (German) ↔ QWERTY
  • Colemak ↔ QWERTY
  • Russian ↔ English (common case: "ghbdtn" = "привет")

Useful Resources

  • DVORAK Keyboard Layout
  • Online DVORAK Decoder ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍