z3 python z3.If всегда False (keygen) - PullRequest
0 голосов
/ 06 октября 2018

Я хочу сгенерировать кейген в python с z3.вот функция проверки:

def f(a):
    a = ord(a)
    if a <= 47 or a > 57:
        if a <= 64 or a > 98:
            exit()
        else:
            return a - 55
    else:
        return a - 48


def validate(key):
    if len(key) != 16:
        return False

    for k in key:
        if f(k)%2== 0:
            return False
    return True

Я попытался написать решатель для этого

from z3 import *
solver = Solver()

def f_z3(a):
    return If(
        Or(a<=47, a>57),
        If(
            Or(a<=64, a>98),
            False, #  exit()???
            a -55
        ),
        a -48
    )

key = IntVector("key", 16)
for k in key:
    solver.add(f_z3(k)%2==0)

solver.check()
print(solver.model())

, а вот вывод

[key__1 = 48,
 key__10 = 48,
 key__9 = 48,
 key__15 = 48,
 key__6 = 48,
 key__8 = 48,
 key__4 = 48,
 key__0 = 48,
 key__14 = 48,
 key__11 = 48,
 key__7 = 48,
 key__5 = 48,
 key__2 = 48,
 key__12 = 48,
 key__13 = 48,
 key__3 = 48]

, который возвращает ключ«0000000000000000», но validate («0000000000000000») возвращает False.

Я знаю, что проблема в функции f_z3, я не знаю, как выразить exit() внутри if, Iхочу что-то всегда Ложь.Но вместо этого я просто возвращаю False.

Есть идеи, как решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 07 октября 2018

Что касается второго пункта, который я не заметил, я был более сконцентрирован в первом.возвращение 1 не решает мои грехи проблемы Я просто упростил реальную проблему с помощью меньшего примера.Я хочу общее решение для этого шаблона.

def f(x):
   if condition(x):
       exit()
   else:
       return g(x) # return something in relation with x

Я нашел этот шаблон, который работает сейчас

def f_z3(x):
    global solver
    solver.add(Not(condition(x))
    return g(x)

Так что моей первой функцией будет что-то вроде

def f_z3(a):
    global solver
    # sins we have two nested condition we have to add an And
    solver.add(
        Not(
            And(
                Or(a<=47, a>57),
                Or(a<=64, a>98)
            )
        )
    )
    return If(
        Or(a<=47, a>57),
        a-55,
        a - 48
    )

Я все еще ищу лучший подход для решения этого типа паттерна, который говорит, что условие If всегда ложно.

0 голосов
/ 07 октября 2018

С вашим кодом есть две проблемы:

  1. Как вы заметили, замена exit на False не совсем подходит для функции f_z3.(Версия Python здесь просто причудливая, в некоторых случаях она возвращает логическое значение и просто умирает в других. Но это не относится к делу.) Во всех других ветвях вы возвращаете целое число, а в той - возвращаетелогическое.В z3 вы всегда хотите вернуть один и тот же тип;целое числоТак что выберите что-то, что в конечном итоге приведет к тому, что False.Поскольку позже вы проверяете четность, подойдет любое нечетное число.Скажи 1;поэтому измените его для получения 1 вместо False при вызове exit.

  2. Пока вы проверяете, код Python возвращает False, если результат четный;так что вам нужно это правильно утверждать.В настоящее время вы делаете solver.add(f_z3(k)%2==0), вместо этого вы должны требовать, чтобы модуль был неравномерным, например: solver.add(f_z3(k)%2!=0).

С этими двумя модификациями вы получитеследующий код:

from z3 import *
solver = Solver()

def f_z3(a):
    return If(
        Or(a<=47, a>57),
        If(
            Or(a<=64, a>98),
            1,
            a -55
        ),
        a -48
    )

key = IntVector("key", 16)
for k in key:
    solver.add(f_z3(k)%2!=0)

solver.check()
print(solver.model())

При запуске это выдает:

[key__1 = 49,
 key__10 = 49,
 key__9 = 49,
 key__15 = 49,
 key__6 = 49,
 key__8 = 49,
 key__4 = 49,
 key__0 = 49,
 key__14 = 49,
 key__11 = 49,
 key__7 = 49,
 key__12 = 49,
 key__5 = 49,
 key__2 = 49,
 key__13 = 49,
 key__3 = 49]

, который предлагает действительный ключ "1111111111111111".

...