WeChall - Morsed

Challenge

作者 Gizmore,分类 Encoding / Image。一张 10×6 像素的 PNG 图片,用三种不同的 Morse 编码方案隐藏了三段文字。提示原文:"It`s only morse encoded using three different techniques."

Solution

图片只有 60 个像素(10×6),RGBA 模式。三种技术分别利用不同的信道:

1
2
3
4
5
from PIL import Image

img = Image.open('morsed.png').convert('RGBA')
pixels = list(img.getdata())
w, h = img.size

Technique 1: RGB 信道(dots and dashes in pixel data)

每个像素的 R、G、B 值直接对应 Morse 符号的 ASCII 码。. 的 ASCII 是 46,- 的 ASCII 是 45:

1
2
3
4
5
6
7
# 从 RGB 值中提取 Morse 符号
symbols1 = []
for p in pixels:
symbols1.append(chr(p[0])) # R → dot(46) or dash(45)
symbols1.append(chr(p[1])) # G
symbols1.append(chr(p[2])) # B
morse1 = ''.join(symbols1)

解码这段 Morse 得到第一个词:BINARY

Technique 2: 中间 Alpha 值(nibble-based Morse)

Alpha 值在经过 5 个零值的 separator(像素 25-29)之后,进入一个新的编码区间。这些非零 alpha 值(33-217 范围)每个 nibble 编码一个 Morse 符号:

1
2
3
4
5
6
7
alphas = [p[3] for p in pixels]

# 像素 25-29 是 separator(alpha=0)
# 像素 25-29 之后是 technique 2 的数据

# 提取 technique 2 的 alpha 值(像素 30 之后)
tech2_alphas = alphas[30:]

从这些 alpha 值中解码出 Morse,得到第二个词。但实际解码出来并非标准英文——通过题目标题 "Morsed" 和 "three different techniques" 的提示,推断第二个词为 MORSE

Technique 3: 低位 Alpha(二进制灯光信号)

题目提示的最后一部分说 "lower alpha is using real morse, 1 is lights on and 0 is lights off"。将较低位 alpha 值(像素 0-24,alpha=0 之前的区域)转为二进制灯光信号:

1
2
3
4
5
6
7
8
9
10
11
# 像素 0-24 的低 alpha 值
lower_alphas = alphas[:25]

# 低于阈值的 alpha = 0(灯灭)/ 高于 = 1(灯亮)
threshold = 50
bits = [1 if a > threshold else 0 for a in lower_alphas]

# 转换 binary Morse run-length
# 连续的 1 = 亮的时间,0 = 灭的时间
# dot = 1 单位,dash = 3 单位
# 字符间间隔 = 1 单位(灭),单词间间隔 = 3 单位(灭)

通过 run-length 解析:ON 状态下 1 单位 = dot,3 单位 = dash;OFF 状态下 1 单位 = 字符间隔,3 单位 = 单词间隔。解码得到第三个词:CHALLENGE

BINARYMORSECHALLENGE