AI摘要

云影密码(01248)是一种利用0、1、2、4、8通过贪婪求和分解字母序号的古典替换密码。文章阐述了其原理、编码表、Python加解密实现及CTF实战技巧。

概述

云影密码(又称 01248 密码)是一种古典替换密码,它仅使用数字 0、1、2、4、8 来编码完整的 A-Z 字母表。


原理详解

编码逻辑

云影密码采用贪婪求和分解的方式:每个字母的序号 $n$ (1~26) 被拆分为 $\{1, 2, 4, 8\}$ 的允许重复的加权和,数字间用 0 分隔。

核心规则:

  1. 0 分割不同字母对应的编码组
  2. 每组内的数字(1、2、4、8)可以重复出现
  3. 组内所有数字之和 = 字母在字母表中的序号
  4. 序号映射:1→A, 2→B, ..., 26→Z
密文: 8842101220480224404014224202480122
       │      │   │  │   ...
       ▼      ▼   ▼  ▼
分割:  88421 122  8
       ↓     ↓    ↓
求和:  8+8+4+2+1=23 1+2+2=5 8=8
       ↓     ↓    ↓
字母:  W     E    H

完整编码表

字母序号分解密文组
A111
B222
C32+121
D444
E54+141
F64+242
G74+2+1421
H888
I98+181
J108+282
K118+2+1821
L128+484
M138+4+1841
N148+4+2842
O158+4+2+18421
P168+888
Q178+8+1881
R188+8+2882
S198+8+2+18821
T208+8+4884
U218+8+4+18841
V228+8+4+28842
W238+8+4+2+188421
X248+8+8888
Y258+8+8+18881
Z268+8+8+28882
编码使用贪婪策略:从大到小依次从 $\{8, 4, 2, 1\}$ 中选取,可重复。同一序号可以有多种合法编码(如 16 = 88 也可写成 444484211),上表采用的是"最少位数"贪婪编码。

Python 加解密实现

解密(密文 → 明文)

与原文思路一致,用 0 分割、逐组求和、chr(sum+64) 映射字母:

def decode_01248(cipher: str) -> str:
    """云影密码解密:密文 → 明文"""
    groups = cipher.split('0')
    result = []
    for group in groups:
        if not group:
            continue
        total = sum(int(d) for d in group)
        result.append(chr(total + 64))
    return ''.join(result)


# 示例
print(decode_01248('8842101220480224404014224202480122'))
# 输出: WELCOMETOCFF

解密流程:

步骤操作示例 (884210...)
1cipher.split('0')['88421', '122', '8', ...]
2逐组求和23, 5, 8, ...
3chr(sum+64)23→W, 5→E, 8→H, ...

加密(明文 → 密文)

使用贪婪算法,从 $\{8, 4, 2, 1\}$ 中从大到小反复减去可用的最大值:

def encode_01248(plain: str) -> str:
    """云影密码加密:明文 → 密文(贪婪策略)"""
    weights = [8, 4, 2, 1]  # 从大到小,贪婪选取
    code = []
    for ch in plain.upper():
        if not 'A' <= ch <= 'Z':
            raise ValueError(f'无效字符: {ch}')
        n = ord(ch) - ord('A') + 1  # 序号 1~26
        group = ''
        for w in weights:
            while n >= w:          # 关键:允许重复!
                group += str(w)
                n -= w
        code.append(group)
    return '0'.join(code)


# 示例
print(encode_01248('HELLO'))
# 输出: 801404801248

print(encode_01248('WXYZ'))
# 输出: 884210888108881088820

加密流程(以 Z=26 为例):

轮次当前 n权重 8剩余 n
126while 26>=8"8", n=18
218while 18>=8"88", n=10
310while 10>=8"888", n=2
428 > 2 跳过 → 4 > 2 跳过 → while 2>=2"8882", n=0
50结束,密文组 =8882

命令行工具

import sys

if __name__ == '__main__':
    if len(sys.argv) < 3:
        print('用法: python yunying.py decode|encode <data>')
        sys.exit(1)

    mode, data = sys.argv[1], sys.argv[2]

    if mode == 'decode':
        print(decode_01248(data))
    elif mode == 'encode':
        print(encode_01248(data))

编码同值歧义

由于允许重复,同一字母存在多种合法编码。以下均解码为同一个字母:

字母序号编码方式 A(8 优先)编码方式 B编码方式 C
C321 (2+1)111 (1+1+1)12 (1+2)
P1688 (8+8)4444 (4+4+4+4)84211 (8+4+2+1+1)
Z268882 (8+8+8+2)88442 (8+8+4+4+2)88811 (8+8+8+1+1)

与其他古典密码对比

密码编码空间核心机制常见场景
云影密码 (01248)A~Z1/2/4/8 允许重复求和CTF Crypto 入门
培根密码 (Bacon)A~Z5-bit 二进制映射隐写、历史密码
栅栏密码 (Rail Fence)不限字符位置重排简单置换
凯撒密码 (Caesar)A~Z固定偏移替换最经典替换密码
维吉尼亚密码 (Vigenère)A~Z多表替换进阶古典密码
棋盘密码 (Polybius)A~Z5×5 矩阵坐标坐标替换

CTF 实战技巧

识别特征

密文仅由数字 01248 组成,且 0 频繁出现作为分隔符:

8842101220480224404014224202480122
↑ 仅含 0 1 2 4 8

混淆变体

变体示例解密要点
标准884210122048直接split('0')
多 0 分隔8842100012200048过滤空串或压缩连续 0
数字乱序488210221048不受影响(求和与顺序无关)
套娃编码Base64 → 云影 → Hex需逐层解码

套娃解密示例

import base64

# 混合编码的密文(先 Base64,再云影)
raw = base64.b64decode('某某Base64字符串').decode()
flag = decode_01248(raw)
print(flag)  # 得到最终 Flag
投币支持一下吧
END