Z3基础学习 (二) 基础语法

Z3基础学习 (二) 基础语法

一.设置变量

Int - 整数型

# 声明单个变量
x = Int('x')
# 声明多个变量
y,z = Ints('y z')
  • | 运算需要初始化为Int变量

Real - 实数型

# 声明单个变量
x = Real('x')
# 声明多个变量
y,z = Reals('y z')

BitVec - 向量(位运算)

# 声明单个 16 位的变量
x = BitVec('x',16)
# 声明多个 16 位的变量
y,z = BitVecs('y z',16)
  • 只有 BitVec 变量可以进行异或
python solver.add(BitVec('x',8)^BitVec('y',8)==5)
  • BitVec 变量值之间可进行>或<或=或>=或<=的比较
BitVec('a',8)>=BitVec('b',8)   
BitVec('a',8)<=BitVec('b',8)   
BitVec('a',8)<=9   BitVec('a',8)==9 
  • BitVecVal 值之间不能进行>或<比较,只能转换成 python 认识的类型才可以比较
if BitVecVal(98,8)>BitVecVal(97,8)#错误,不是python类型  
if BitVecVal(98,8)==98:   
if BitVecVal(98,8).as_long()>97   
if BitVecVal(98,8).as_long()>BitVecVal(97,8).as_long()

变量设置的类型可能会影响到最后求解的结果。可以先 check 一下看看有没有解,然后再判断是否需要切换变量的类型。

二.Solver 对象

实际做题时,约束条件肯定不会想上面例子这么少,所以需要实例化一个 Solver() 对象,方便我们添加更多的约束条件。

创建约束求解器:

solver = Solver()

三.添加约束条件

一行一个约束条件,这里的约束条件就是方程等式:

solver.add(x**2+y**2==74)
solver.add(x**5-y==z)
# [y = -7, x = 5, z = 3132]

z3 中不允许列表与列表之间添加==约束条件:

from z3 import *
prefix=[ord(each) for each in "flag{"]
plain_line=[Int('x%d' % i) for i in range(5)]
s=Solver()
z=0
#s.add(plain_line[z:z+5]==prefix) 列表==列表-->错误
s.add(plain_line[z]==prefix[0])
s.add(plain_line[z+1]==prefix[1])
s.add(plain_line[z+2]==prefix[2])
s.add(plain_line[z+3]==prefix[3])
s.add(plain_line[z+4]==prefix[4])
s.check()
print(s.model())

四.判断是否有解

if solver.check() == sat:
    print("solver")
else:
    print("no solver")

五.求解并输出

ans = solver.model()
print(ans)

六.限制结果为可见字符

通常如果是做题的话,解密出来很可能是 flag ,也就是 ascii 码,所以为了进一步约束范围可以给每一个变量都加上额外的一条约束,约束其结果只能在可见 ascii 码范围以内:

solver.add(x < 127)
solver.add(x >= 32)

七.快速添加变量

添加 50 个 Int 变量 s :

s=[Int('s%d' % i) for i in range(50)]

添加 50 个 Real 变量 s :

s=[Real('s%d' % i) for i in range(50)]

添加 50 个 16 位 BitVec 变量 s :

s=[BitVec ('s%d' % i,16) for i in range(50)]

在约束条件中用下标索引使用:

solver.add(s[18] * s[8] == 5)
solver.add(s[4] * s[11] == 0)

将结果按顺序打印出来:

这是使用列表管理变量的好处,如果不使用列表 print(answer) 输出的结果是无序的。

answer=solver.model()
#print(answer)
result="".join([str(answer[each]) for each in s])
print(result)
posted @ 2022-12-28 03:05  说芬兰语的雪  阅读(164)  评论(0编辑  收藏  举报