PUZZLE1
0110 0100
0110 0001
0111 0100
0110 0001
SOLVE1
通过 ASCII 码表可知,明文为 data
。
PUZZLE2
HELLO
0011 1111
0010 1010
0011 1110
0010 0000
0010 1011
SOLVE2
容易猜出答案是 world
,不过如何得到的呢?
考虑将 HELLO
换为 ASCII 码形式,即
0100 1000
0100 0101
0100 1100
0100 1100
0100 1111
进行 XOR
运算可以得到
0111 0111
0110 1111
0111 0010
0110 1100
0110 0100
即 world
。
PUZZLE3
2131 2572
0110 0010
0111 0101
0111 1001
0110 0011
0111 0101
0110 0110
0110 1001
SOLVE3
通过第一行的数字,我们按竖直方向进行移位,可以得到
0110 0010
0110 1001
0111 0100
0111 0111
0110 1001
0111 0011
0110 0001
也就是说答案为 bitwise
。
PUZZLE4
[img]
1111 1110, 0000 0001, 0000 0000, 0000 0001
1111 1110, 1111 1110, 1111 1110, 0000 0000
1111 1110, 1111 1111, 1111 1110, 0000 0000
0000 0000, 1111 1111, 0000 0001, 0000 0001
SOLVE4
通过提示,我们得知这极有可能是一张 IMG
图像,转换为数字后可以得到
254 | 1 | 0 | 1 |
---|---|---|---|
254 | 254 | 254 | 0 |
254 | 255 | 254 | 0 |
0 | 255 | 1 | 1 |
把 254
,255
看做白色,0
,1
看做黑色,可以读出 .J
两个字符。
接下来考虑 LSB 隐写,可以得到四组四位二进制数。
0101
0000
0100
0111
拼接后可以得到
0101 0000 -> P
0100 0111 -> G
因此明文为 .JPG
,也是一种图像格式。
PUZZLE5
SOLVE5
这是 AES
加密算法中的行列混淆,我们可以通过编写一个程序来直观的感受一下。
def shift_rows(s):s[0][1], s[1][1], s[2][1], s[3][1] = s[1][1], s[2][1], s[3][1], s[0][1]s[0][2], s[1][2], s[2][2], s[3][2] = s[2][2], s[3][2], s[0][2], s[1][2]s[0][3], s[1][3], s[2][3], s[3][3] = s[3][3], s[0][3], s[1][3], s[2][3]def mix_single_column(a):# see Sec 4.1.2 in The Design of Rijndaelt = a[0] ^ a[1] ^ a[2] ^ a[3]u = a[0]a[0] ^= t ^ xtime(a[0] ^ a[1])a[1] ^= t ^ xtime(a[1] ^ a[2])a[2] ^= t ^ xtime(a[2] ^ a[3])a[3] ^= t ^ xtime(a[3] ^ u)def mix_columns(s):for i in range(4):mix_single_column(s[i])
每次混淆之后对密钥进行异或操作即可,两轮后得到矩阵:
0100
0110
0100
1110
可以得知明文为 FN
。