前言:为什么要学内置函数?
在数据安全比赛(尤其是 CTF)中,速度就是一切。 很多时候,你不需要写几百行的代码,也不需要安装庞大的第三方库(如 numpy),只需要巧妙地组合 Python 的内置函数,一行代码就能解决问题。
例如:
-
进制转换 :
int("1010", 2) -
字符编码 :
chr(65),ord('A') -
异或操作 :
zip(),map() -
列表检查 :
all(),any()
本教程将挑选出 解题脚本中最常用 的内置函数,配合实战场景进行讲解。
第一部分:进制与编码转换 (最核心)
在 Crypto(密码学)和 Misc(杂项)题目中,数据经常在二进制、十进制、十六进制、ASCII 码之间变来变去。
1.1 进制转换四剑客:bin, oct, hex, int
-
bin(x): 转二进制 (前缀0b) -
oct(x): 转八进制 (前缀0o) -
hex(x): 转十六进制 (前缀0x) -
int(x, base): 万能转十进制
实战场景:处理十六进制数据
num = 255
# 1. 转十六进制
print(hex(num)) # '0xff'
# 2. 只有 hex() 经常不够用,因为它带 '0x' 前缀。
# 比赛常用技巧:使用 format 去掉前缀并补零
print(f"{num:02x}") # 'ff' (小写,补齐2位)
print(f"{num:02X}") # 'FF' (大写)
# 3. 任意进制转十进制
print(int("1101", 2)) # 13 (二进制转十进制)
print(int("FF", 16)) # 255 (十六进制转十进制)
print(int("17", 8)) # 15 (八进制转十进制)
# 甚至支持 36 进制 (0-9, a-z)
print(int("Z", 36)) # 35
1.2 ASCII 与字符互转:chr, ord
这是凯撒密码(Caesar Cipher)和许多位移密码的基础。
-
ord(c): 字符 -> ASCII 数值 (Ordinal) -
chr(i): ASCII 数值 -> 字符 (Character)
实战场景:凯撒密码解密
题目:将字符串 "ifmmp" 每个字母向前移 1 位。
cipher = "ifmmp"
plain = ""
for c in cipher:
# 1. 转数字 -> 2. 减 1 -> 3. 转回字符
plain += chr(ord(c) - 1)
print(plain) # hello
# 高手写法 (列表推导式 + join)
print("".join([chr(ord(c) - 1) for c in cipher]))
第二部分:数据结构与迭代 (数据处理)
当你要处理一堆 IP 地址、一堆字符或者两个文件内容的对比时,这些函数是神器。
2.1 缝合怪:zip(*iterables)
功能 : 把两个或多个列表"拉链"一样对应打包在一起。 场景 : 异或解密 (XOR)。这是 CTF 中出现频率最高的操作之一。
实战场景:多字节异或 (XOR)
假设你知道密文是 cipher,密钥是 key,需要将它们逐字节异或。
cipher = [0x1f, 0x2d, 0x3a]
key = [0x55, 0x55, 0x55]
# 普通写法
result = []
for i in range(len(cipher)):
result.append(cipher[i] ^ key[i])
# zip 写法 (优雅、Pythonic)
# zip(cipher, key) 会生成: (0x1f, 0x55), (0x2d, 0x55), (0x3a, 0x55)
result = [c ^ k for c, k in zip(cipher, key)]
print(result) # [74, 120, 111] -> ascii: Jxo
2.2 带索引遍历:enumerate(iterable)
功能 : 遍历列表时,同时给你 索引 (index) 和 值 (value) 。 场景: 当你需要知道当前处理到第几个字符时(比如奇数位做一种操作,偶数位做另一种)。
data = "abcdef"
# 题目:将偶数位变成大写,奇数位保持不变
result = ""
for index, char in enumerate(data):
if index % 2 == 0:
result += char.upper()
else:
result += char
print(result) # AbCdEf
2.3 逻辑判断:all(), any()
-
all(iterable): 如果所有元素都为真,返回 True。(类似 AND) -
any(iterable): 只要有一个元素为真,返回 True。(类似 OR)
实战场景:暴力破解检测
# 假设这是爆破出来的结果,我们需要判断是否包含只有可打印字符的解
results = ["\x00\x01\x02", "flag{abc}", "\xff\xfe"]
import string
printable = set(string.printable)
for res in results:
# 检查 res 中的每一个字符 c 是否都在 printable 集合里
if all(c in printable for c in res):
print(f"找到可能的解: {res}")
2.4 排序与反转:sorted(), reversed()
-
sorted(iterable, key=..., reverse=...): 排序,返回新列表。 -
reversed(seq): 反转序列。
实战场景:频率分析
统计一段密文中出现次数最多的字符。
text = "aaabbbaacccdddd"
# 使用 set 去重拿到所有字符
unique_chars = set(text)
# 按照字符在 text 中出现的次数排序
# key 参数指定排序规则:text.count
# reverse=True 表示降序(出现最多的排前面)
sorted_chars = sorted(unique_chars, key=text.count, reverse=True)
print(sorted_chars) # ['d', 'a', 'c', 'b'] (d出现了4次,a3次...)
第三部分:数学与逻辑运算
3.1 模幂运算:pow(base, exp, mod)
功能 : 计算 (base ** exp) % mod。 场景 : RSA 加密/解密 。 注意 : 千万不要写成 (a ** b) % c!当 b 很大时(比如 1024 位的大整数),先算乘方会把内存撑爆或者算到天荒地老。pow(a, b, c) 使用了快速幂算法,秒出结果。
# RSA 场景
c = 123456789 # 密文
d = 65537 # 私钥指数
n = 999999999 # 模数
# 解密 m = c^d mod n
m = pow(c, d, n) # 极快
print(m)
3.2 商余运算:divmod(a, b)
功能 : 同时返回商和余数 (a // b, a % b)。 场景: 进制转换算法、分页计算。
seconds = 3665
minutes, sec = divmod(seconds, 60)
hours, min = divmod(minutes, 60)
print(f"{hours}h {min}m {sec}s") # 1h 1m 5s
第四部分:动态执行 (双刃剑)
在 CTF 的 Python Jail(沙箱逃逸)题目中,这几个函数是核心考点;在写脚本时,它们可以动态执行代码。
4.1 字符串当代码跑:eval(), exec()
-
eval(expression): 执行一个表达式,有返回值。 -
exec(object): 执行一段代码块,无返回值。
实战场景:计算器题目
题目:服务器返回一个数学算式 "123 * 45 + 67",要求你在 1 秒内算出结果并发回。
equation = "123 * 45 + 67"
result = eval(equation) # 自动识别优先级计算
print(result) # 5602
⚠️ 警告 : 永远不要对不可信的输入使用
eval!如果输入是__import__('os').system('rm -rf /'),你的电脑就完了。
第五部分:输入输出与文件
5.1 构造 Payload:print 的骚操作
在构造 Exploit 时,有时候不能自动换行,或者需要输出二进制流。
# end="" 禁止换行
print("正在爆破...", end="")
print("完成")
# 输出到标准错误 (stderr)
import sys
print("Debug信息", file=sys.stderr)
5.2 快速文件操作:open
# 1. 读取二进制文件 (图片、程序) -> 'rb'
with open("flag.jpg", "rb") as f:
data = f.read()
# 寻找文件头
if data.startswith(b'\xff\xd8\xff'):
print("这是一个 JPG 图片")
# 2. 写入二进制 -> 'wb'
with open("output.bin", "wb") as f:
f.write(b'\x00\x01\x02')
第六部分:调试与自省 (Introspection)
当你拿不到文档,或者面对一个混淆的对象时,这些函数能救命。
6.1 我是谁?type(), id(), isinstance()
x = 123
print(type(x)) # <class 'int'>
if isinstance(x, int):
print("是整数")
6.2 我有什么?dir(), help()
-
dir(obj): 列出对象所有的属性和方法。 -
help(obj): 查看帮助文档。
实战场景:探索未知对象
假设你在解一道 Python 反序列化题,拿到了一个奇怪的对象 obj。
# 看看它有什么方法可以利用?
print(dir(obj))
# 输出: ['__class__', '__delattr__', ... 'secret_function', 'user_data']
# 发现有个 secret_function,看看怎么用
# help(obj.secret_function)
总结:常用内置函数速查表
| 类别 | 函数 | 描述 | 典型场景 |
|---|---|---|---|
| 转换 | int(x, base) |
任意进制转十进制 | 进制转换 |
bin/hex/oct |
转二/十六/八进制 | 数据展示 | |
chr/ord |
字符/ASCII互转 | 凯撒密码、位移 | |
| 逻辑 | all/any |
全真/任一真 | 爆破结果检查 |
| 数据 | zip |
打包迭代 | 异或 (XOR) |
enumerate |
带索引遍历 | 奇偶位不同处理 | |
sorted |
排序 | 频率分析 | |
len |
长度 | 检查 Flag 长度 | |
| 数学 | pow(a,b,c) |
模幂运算 | RSA 解密 |
divmod |
商余 | 时间/单位换算 | |
| 执行 | eval |
执行表达式 | 算式计算 (慎用) |
| 自省 | dir |
列出属性 | 探索未知对象/沙箱逃逸 |
掌握这些函数,你的 Python 脚本将变得短小精悍 且高效!