基本数据类型 :
在Python中使用Z3模块,我们的所求结果一般有以下几种数据类型:
Int #整型
Bool #布尔型
Array #数组
BitVec ( ‘a’,8 ) #char型
其中BitVec可以是特定大小的数据类型,不一定是8,例如C语言中的int型可以用BitVec(‘a’,32)表示
设未知数的方法 :
可以使用 ‘Int’ , ‘Real’ , ‘BitVec’ 等声明一个整数或实数变量,也可以申明一个变量数组
例如:x = Int(‘x’) #这个int不是c/c++中的那个,而仅仅只代表整数
1 2 3 4
| y =Real('y') z =BitVec('z',8) w =BitVec('w',32) p =Bool('p')
|
初始化序列:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| flag = [] for i in range(5): flag.append(BitVec('%d' % i, 8)) print(flag)
flag= [Int('%d' % i) for i in range(32)] flag = [] for i in range(5): flag.append(BitVec('%d' % i, 32)) print(flag)
|
二:基本使用语法:
Solver()
Solver()命令会创建一个通用求解器,创建后我们可以添加我们的约束条件,进行下一步的求解
add()
add()命令用来添加约束条件,通常在solver()命令之后,添加的约束条件通常是一个逻辑等式
check()
该函数通常用来判断在添加完约束条件后,来检测解的情况,有解的时候会回显sat,无解的时候会回显unsat
model()
在存在解的时候,该函数会将每个限制条件所对应的解集的交集,进而得出正解。
常用求解步骤:
创建约束求解器
添加约束条件(这一步是z3求解的关键)
判断解是否存在
1
| if solver.check() == sat:
|
求解
1
| print ( solver.model() )
|
题目示例
尝试求解 try 部分内容 :
其中的 key_cmp 对应的分别为 S
y
c
l
o
v
e
r
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| from z3 import *
key1 = BitVec('key1',32) key2 = BitVec('key2',32) key3 = BitVec('key3',32) key4 = BitVec('key4',32) key5 = BitVec('key5',32) key6 = BitVec('key6',32) key7 = BitVec('key7',32) key8 = BitVec('key8',32)
key = Solver()
key.add((key2 * key3 - key6 * 72 - key5 * 3 - key4 ^ key2 + (key4 << 2) + key3 * 6 - key8 & key7 - 1000) - 14==ord('S'))
key.add(((key6 * 7 + key4 * 3 + key3 + key7 - (key3 >> 2) - key2 ^ key1 + key8 + (key5 ^ key2) + (key5 | key8)) - 801)==ord('y'))
key.add(((key7 * 5 + key3 * 6 - key4 * 7 + key5 | key6 + key5 * 10 + key1 ^ key2 * 3 - key8 + key1 + key2) - 924)==ord('c'))
key.add((key2 * 3 + key6 * 9 + key1 + key3 * 2 + key4 * 5 - key5 * (key7 ^ key8) + 321 - 16)==ord('l'))
key.add(((key6 * 12 - key1 ^ key7 - key4 * 23 + key5 * 3 + key3 * 8 + key2 - key8 * 2 + key7 * 4 + 1324) + 1)==ord('o'))
key.add((key4 * 54 - key2 * 3 + key3 * 3 + key5 * 11 - key6 * 2 + key1 + key8 * 3 - key7 - 6298 + 40)==ord('v'))
key.add((key8 - key7 * key4 + key3 * key3 - key5 * 32 + key6 * (key1 >> 2) - key2 * key2 - 6689 + 41)==ord('e'))
key.add(((key6 - key4 * 41 + key7 * 41 + key6 ^ (key5 & key7 | key1) - (key8 * 24 | key3) + key2 - 589) - 36)==ord('r'))
if key.check()==sat: print(key.model()) else: print("WA")
|
输出为 :