Decorative image frame

从一道 CTF Misc 题目中发现了一个简洁巧妙的求虚数单位 i 幂的方法

先给结论,Python 的实现:

1
2
3
4
5
def i_pow(n):
return "1i--"[n % 4 :: -2]

a = int(input("Input the exponent: "))
print("i **", a, "=", i_pow(a), sep=" ")

题目:XYCTF 2025 - Misc - sins

题目内容:(没必要看)

1
2
3
“Come now, let us settle the matter,” says the LORD. “Though your sins are like scarlet, they shall be as white as snow; though they are red as crimson, they shall be like wool. - Isaiah 1:18

(出题人:adwa)

题目附件 sins.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from secret import flag

print('For there are three that bear record in heaven, the Father, the Word, and the Holy Ghost')
print('But here we have four cases bearing witness')


def i_pow(n):
if n % 4 == 0: # as the 40 days of flood
return '1'
elif n % 4 == 1: # as the 1 true God
return 'i'
elif n % 4 == 2: # as the 2 tablets of stone
return '-1'
elif n % 4 == 3: # as the 3 days in the tomb
return '-i'

inp = input("wash away your sins: ")
assert all(i in "i0123456789+-*%/^=<>~&|:()[]'" for i in inp), "invalid char"
assert len(inp) < 16, "too long"
R = eval(f"lambda i: {inp}", {}, {})
assert all(R(i) == i_pow(i) for i in range(int.from_bytes(b'The_adwa_shall_forgive_thee') // 2**195))
print(flag)

题解 WriteUp

分析代码可知,我们需要编写一个 Python Lambda 表达式,题目对这个表达式的要求是:

  1. 只能包含 i0123456789+-*%/^=<>~&|:()[] 这些字符,不可以出现 逗号,、空格 、除了 i 的其它字母 等等。
  2. 长度小于 16.
  3. 不能访问任何全局变量或函数,只能使用表达式中的运算和 i 变量。
  4. 以字符串类型返回虚数单位 $$i$$传入参数 i 次幂。也就是说结果是在 1 i -1 -i 循环。

开始看题后,搓了两个小时,终于得到了最终的表达式,且长度为 15,成功满足了题目所有要求:

1
'1i--'[i%4::-2]

flag: XYCTF{Thy_sins_are_forgiven_thee}

最终一共有 8 队伍解出。这题可谓是把 Python 的字符串截取玩到一定境界了,思路也很重要。