• XSS.stack #1 – первый литературный журнал от юзеров форума

Генерация чисел

а временные затраты окупятся? или это так и останется Proof of concept.
Реализуй подобное в своём project - тогда и узнаешь.
Будут вопросы - обращайся, чем смогу - помогу.
 
Реализуй подобное в своём project - тогда и узнаешь.
Будут вопросы - обращайся, чем смогу - помогу.
для начала нужно дорасти до 100сообщений чтоб посмотреть предложения товарища Left4Dead
 
Мне кажется нерационально генерировать случайные деревья и проверять потом, а не подходит ли это дерево под нашу задачу, в частности подстановка и проверка ожидаемого выхода, медленно достаточно
Мне кажется лучше генерировать случайное дерево, делать рассчет получая Y из входного X, затем просто строить обратное дерево преобразований, отзеркаливающих действия, по итогу получаем дерево, которому на вход подается Y, а на выход получаем X
Так гораздо быстрее, и не нарушается оригинальная концепция, просто вместо функции проверки формулы на валидность для нашего случая надо написать генератор дерева функции-инверсии
 
Мне кажется нерационально генерировать случайные деревья и проверять потом, а не подходит ли это дерево под нашу задачу, в частности подстановка и проверка ожидаемого выхода, медленно достаточно
Мне кажется лучше генерировать случайное дерево, делать рассчет получая Y из входного X, затем просто строить обратное дерево преобразований, отзеркаливающих действия, по итогу получаем дерево, которому на вход подается Y, а на выход получаем X
Так гораздо быстрее, и не нарушается оригинальная концепция, просто вместо функции проверки формулы на валидность для нашего случая надо написать генератор дерева функции-инверсии
post-order traversal?
 
Мб кому пригодится, Python 3.9

Python:
import secrets

TREE_NODE_OPERAND = 0
TREE_NODE_UNARY = 1
TREE_NODE_BINARY = 2
TREE_MAX_DEPTH = 8

unary_array = []
binary_array = []


def calculate_unary(a, opcode):
    if opcode == 0x00:
        return a
    elif opcode == 0x01:
        return ~a & 0xFF
    elif opcode == 0x02:
        return (a + 1) & 0xFF
    elif opcode == 0x03:
        return (a - 1) & 0xFF
    elif opcode == 0x04:
        return a >> 1
    elif opcode == 0x05:
        return a >> 2
    elif opcode == 0x06:
        return a >> 3
    elif opcode == 0x07:
        return a >> 4
    elif opcode == 0x08:
        return (a << 1) & 0xFF
    elif opcode == 0x09:
        return (a << 2) & 0xFF
    elif opcode == 0x0A:
        return (a << 3) & 0xFF
    elif opcode == 0x0B:
        return (a << 4) & 0xFF


def unary_to_string(operand, opcode):
    if opcode == 0x00:
        return f"(unsigned char)( {operand} )"
    elif opcode == 0x01:
        return f"(unsigned char)( ~( (unsigned char){operand} ) )"
    elif opcode == 0x02:
        return f"(unsigned char)( (unsigned char){operand} + 1 )"
    elif opcode == 0x03:
        return f"(unsigned char)( (unsigned char){operand} - 1 )"
    elif opcode == 0x04:
        return f"(unsigned char)( (unsigned char){operand} >> 1 )"
    elif opcode == 0x05:
        return f"(unsigned char)( (unsigned char){operand} >> 2 )"
    elif opcode == 0x06:
        return f"(unsigned char)( (unsigned char){operand} >> 3 )"
    elif opcode == 0x07:
        return f"(unsigned char)( (unsigned char){operand} >> 4 )"
    elif opcode == 0x08:
        return f"(unsigned char)( (unsigned char){operand} << 1 )"
    elif opcode == 0x09:
        return f"(unsigned char)( (unsigned char){operand} << 2 )"
    elif opcode == 0x0A:
        return f"(unsigned char)( (unsigned char){operand} << 3 )"
    elif opcode == 0x0B:
        return f"(unsigned char)( (unsigned char){operand} << 4 )"


def calculate_binary(a, b, opcode):
    if opcode == 0x00:
        return a & b
    elif opcode == 0x01:
        return a ^ b
    elif opcode == 0x02:
        return a | b
    elif opcode == 0x03:
        return (a + b) & 0xFF
    elif opcode == 0x04:
        return (a - b) & 0xFF
    elif opcode == 0x05:
        return (a * b) & 0xFF


def binary_to_string(operand_left, operand_right, opcode):
    if opcode == 0x00:
        return f"( {operand_left} & {operand_right} )"
    elif opcode == 0x01:
        return f"( {operand_left} ^ {operand_right} )"
    elif opcode == 0x02:
        return f"( {operand_left} | {operand_right} )"
    elif opcode == 0x03:
        return f"( {operand_left} + {operand_right} )"
    elif opcode == 0x04:
        return f"( {operand_left} - {operand_right} )"
    elif opcode == 0x05:
        return f"( {operand_left} * {operand_right} )"


def precalculate_unary_array():
    global unary_array
    sz = (0xFF + 1) * (0x0B + 1)
    unary_array = [calculate_unary(a, opcode) for a in range(0x00, 0x100) for opcode in range(0x00, 0x0C)]


def precalculate_binary_array():
    global binary_array
    sz = (0xFF + 1) * (0xFF + 1) * (0x05 + 1)
    binary_array = [calculate_binary(a, b, opcode) for a in range(0x00, 0x100) for b in range(0x00, 0x100) for opcode in
                    range(0x00, 0x06)]


class Tree:
    def __init__(self, t, opcode=None, child_left=None, child_right=None):
        self.type = t
        self.opcode = opcode
        self.child_left = child_left
        self.child_right = child_right


def create_random_tree(depth):
    if depth <= 1:
        return Tree(TREE_NODE_OPERAND)
    else:
        t = secrets.randbelow(3)
        if t == TREE_NODE_UNARY:
            opcode = secrets.randbelow(0x0C)
            return Tree(TREE_NODE_UNARY, opcode=opcode, child_left=create_random_tree(depth - 1))
        elif t == TREE_NODE_BINARY:
            opcode = secrets.randbelow(0x06)
            return Tree(TREE_NODE_BINARY, opcode=opcode, child_left=create_random_tree(depth - 1),
                        child_right=create_random_tree(depth - 1))
        else:
            return Tree(TREE_NODE_OPERAND)


def delete_tree(t):
    if t is not None:
        if t.child_left is not None:
            delete_tree(t.child_left)
        if t.child_right is not None:
            delete_tree(t.child_right)
        t = None


def count_tree(t, operand_value):
    if t.type == TREE_NODE_OPERAND:
        return operand_value
    elif t.type == TREE_NODE_UNARY:
        return unary_array[count_tree(t.child_left, operand_value) * (0x0B + 1) + t.opcode]
    elif t.type == TREE_NODE_BINARY:
        return binary_array[
            count_tree(t.child_left, operand_value) * (0xFF + 1) * (0x05 + 1) + count_tree(t.child_right,
                                                                                           operand_value) * (
                    0x05 + 1) + t.opcode]


def tree_to_string(t, operand):
    if t.type == TREE_NODE_OPERAND:
        return operand
    elif t.type == TREE_NODE_UNARY:
        return unary_to_string(tree_to_string(t.child_left, operand), t.opcode)
    elif t.type == TREE_NODE_BINARY:
        return binary_to_string(tree_to_string(t.child_left, operand), tree_to_string(t.child_right, operand), t.opcode)


def generate_tree(x, y):
    while True:
        t = create_random_tree(TREE_MAX_DEPTH)
        if count_tree(t, x) == y:
            return t
        delete_tree(t)


if __name__ == '__main__':
    precalculate_unary_array()
    precalculate_binary_array()

    with open("genka.c", "w") as f:
        f.write("#include <stdio.h>\nvoid main(){\n    unsigned char x, y, c;\n")

        for i in range(10):
            while True:
                x = secrets.randbelow(256)
                t = create_random_tree(3 + secrets.randbelow(5))
                st = tree_to_string(t, "x")
                y = count_tree(t, x)
                delete_tree(t)
                if x != y:
                    break
            print(f"x = {x}, y = {y}\n{st}\n")

            f.write(f"    x = {x};\n")
            f.write(f"    y = {y};\n")
            f.write(f"    c = {st};\n")
            f.write(f"    if (c != y)\n")
            f.write(f'        printf("x = %d, y = %d, c = %d\\t%s\\n", x, y, c, {st});\n')

        f.write("}\n")
 
Мне кажется нерационально генерировать случайные деревья и проверять потом, а не подходит ли это дерево под нашу задачу, в частности подстановка и проверка ожидаемого выхода, медленно достаточно
Мне кажется лучше генерировать случайное дерево, делать рассчет получая Y из входного X, затем просто строить обратное дерево преобразований, отзеркаливающих действия, по итогу получаем дерево, которому на вход подается Y, а на выход получаем X
Так гораздо быстрее, и не нарушается оригинальная концепция, просто вместо функции проверки формулы на валидность для нашего случая надо написать генератор дерева функции-инверсии
Короче делал твою версию, бред какой-то выходит. Операции то многие не обратимы
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх