Brainfuck примеры реализаций

Март 26, 2024, 12:03 - Время чтения: 3 минуты

Python

def brainfuck_interpreter(code):
    tape = [0] * 30000
    pointer = 0
    output = ""

    brackets = find_brackets(code)

    code_ptr = 0
    while code_ptr < len(code):
        instruction = code[code_ptr]

        if instruction == ">":
            pointer += 1
        elif instruction == "<":
            pointer -= 1
        elif instruction == "+":
            tape[pointer] += 1
        elif instruction == "-":
            tape[pointer] -= 1
        elif instruction == ".":
            output += chr(tape[pointer])
        elif instruction == ",":
            tape[pointer] = ord(input()[:1])
        elif instruction == "[" and tape[pointer] == 0:
            code_ptr = brackets[code_ptr]
        elif instruction == "]" and tape[pointer] != 0:
            code_ptr = brackets[code_ptr]

        code_ptr += 1

    return output

def find_brackets(code):
    brackets = {}
    stack = []

    for i, char in enumerate(code):
        if char == "[":
            stack.append(i)
        elif char == "]":
            open_bracket = stack.pop()
            brackets[open_bracket] = i
            brackets[i] = open_bracket

    return brackets

bf_code = ">+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+.>++++++++++."
output = brainfuck_interpreter(bf_code)
print(output)

C

#include <stdio.h>

#define MEMORY_SIZE 30000

void brainfuck_interpreter(char *code) {
    char memory[MEMORY_SIZE] = {0};
    char* ptr = memory;

    while (*code != '\0') {
        switch (*code) {
            case '>':
                ++ptr;
                break;
            case '<':
                --ptr;
                break;
            case '+':
                ++(*ptr);
                break;
            case '-':
                --(*ptr);
                break;
            case '.':
                putchar(*ptr);
                break;
            case ',':
                *ptr = getchar();
                break;
            case '[':
                if (*ptr == 0) {
                    int loop_count = 1;
                    while (loop_count > 0) {
                        ++code;
                        if (*code == '[') {
                            ++loop_count;
                        } else if (*code == ']') {
                            --loop_count;
                        }
                    }
                }
                break;
            case ']':
                if (*ptr != 0) {
                    int loop_count = 1;
                    while (loop_count > 0) {
                        --code;
                        if (*code == ']') {
                            ++loop_count;
                        } else if (*code == '[') {
                            --loop_count;
                        }
                    }
                }
                break;
        }

        ++code;
    }
}

int main() {
    char bf_code[] = ">+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+.>++++++++++.";

    brainfuck_interpreter(bf_code);

    return 0;
}

C++

#include <iostream>

#define MEMORY_SIZE 30000

void brainfuck_interpreter(char* code) {
    char memory[MEMORY_SIZE] = { 0 };
    char* ptr = memory;

    while (*code != '\0') {
        switch (*code) {
        case '>':
            ++ptr;
            break;
        case '<':
            --ptr;
            break;
        case '+':
            ++(*ptr);
            break;
        case '-':
            --(*ptr);
            break;
        case '.':
            std::cout << *ptr;
            break;
        case ',':
            std::cin >> *ptr;
            break;
        case '[':
            if (*ptr == 0) {
                int loop_count = 1;
                while (loop_count > 0) {
                    ++code;
                    if (*code == '[') {
                        ++loop_count;
                    }
                    else if (*code == ']') {
                        --loop_count;
                    }
                }
            }
            break;
        case ']':
            if (*ptr != 0) {
                int loop_count = 1;
                while (loop_count > 0) {
                    --code;
                    if (*code == ']') {
                        ++loop_count;
                    }
                    else if (*code == '[') {
                        --loop_count;
                    }
                }
            }
            break;
        }

        ++code;
    }
}

int main() {
    char bf_code[] = ">+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.>>>++++++++[<++++>-]<.>>>++++++++++[<+++++++++>-]<---.<<<<.+++.------.--------.>>+.>++++++++++.";

    brainfuck_interpreter(bf_code);

    return 0;
}

Пишем свой антивирус с нуля часть 2

Март 25, 2024, 15:03 - Время чтения: 2 минуты

Как и обещал в предыдущей статье - вот простейший сканер:

import os
import hashlib
from sqlalchemy import create_engine, Column, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

db_path = "file_hashes.db"

engine = create_engine(f"sqlite:///{db_path}")
Session = sessionmaker(bind=engine)
session = Session()

Base = declarative_base()

class FileHash(Base):
    __tablename__ = "file_hashes"
    id = Column(String, primary_key=True)
    filename = Column(String)
    sha256 = Column(String)

Base.metadata.create_all(engine)

def calculate_sha256(file_path):
    hasher = hashlib.sha256()
    with open(file_path, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hasher.update(chunk)
    return hasher.hexdigest()

def add_file_to_db(file_path):
    filename = os.path.basename(file_path)
    sha256 = calculate_sha256(file_path)

    existing_hash = session.query(FileHash).filter_by(sha256=sha256).first()

    if existing_hash:
        print(f"Файл {file_path} уже существует в базе данных.")
        return
    file_hash = FileHash(id=sha256, filename=filename, sha256=sha256)
    session.add(file_hash)
    session.commit()
    print(f"Файл {file_path} успешно добавлен в базу данных.")

def scan_directory(directory):
    n = 0
    v = 0
    for root, dirs, files in os.walk(directory):
        for filename in files:
            file_path = os.path.join(root, filename)
            sha256 = calculate_sha256(file_path)

            existing_hash = session.query(FileHash).filter_by(sha256=sha256).first()
            n += 1
            if existing_hash:
                v += 1
                print(f"{file_path}: Вероятно вирус!")
    return n, v

if __name__ == "__main__":
    directory_to_scan = "/test/"
    n, v = scan_directory(directory_to_scan)

    print(f"Просканировано: {n} файлов")
    print(f"Найдено: {v} угроз")

Для теста написал неприятную программку которая сильно кушает процессорное время:

#include <stdlib.h>

int main() {
    for (;;) { fork(); free(malloc(4096)); }
    return -3;
}

Лучше не запускать её, но я скомпилировал и проверил :) Теперь нужно добавить в базу это недоразумение:

if __name__ == "__main__":
    directory_to_scan = "/test/"
    add_file_to_db('/test/a.out')
    n, v = scan_directory(directory_to_scan)

    print(f"Просканировано: {n} файлов")
    print(f"Найдено: {v} угроз")

Вот примерный вывод программы:

Файл /test/a.out успешно добавлен в базу данных.
/test/a.out: Вероятно вирус!
Просканировано: 4 файлов
Найдено: 1 угроз

В следующей статье будет более наглядный и правильный пример антивирусной программы


Элиза

Август 29, 2023, 11:08 - Время чтения: ~1 минут

ELIZA – это нечто вроде чат-бота, который может "разговаривать" с людьми. ELIZA была создана Джозефом Вейценбаумом в 1966 году. Знаете, как некоторые приложения на вашем телефоне могут отвечать на ваши вопросы и выполнять различные команды (как Сири или Алиса)? ELIZA делает подобное, только ещё более простым образом

Она построена по принципу реагирования на определенные фразы, заданные пользователем. ELIZA задаёт вопросы, основываясь на предыдущих ответах клиента, демонстрируя таким образом "понимание" того, что собеседник сказал.

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

В общем я реализовал эту программу и вскоре в моём телеграм канале появится ссылка на скачивание и веб версию этой программы.


Моя нейросеть для генерации картинок

Июнь 26, 2023, 20:06 - Время чтения: ~1 минут

Эксперимент по обучению нейросети для генерации изображений островов 28 на 28 пикселей я провел в своём телеграм канале.

Variational Autoencoder (VAE) является типом нейронной сети, который может создавать новые данные на основе обучающей выборки. Например, если обучить VAE на изображениях кошек, он сможет создавать новые, ранее не виданные изображения кошек.

VAE состоит из двух частей: энкодера и декодера. Энкодер преобразует входные данные (например, изображение кошки) в латентное пространство - набор значений, описывающих характеристики входных данных, недоступных пользователю. Декодер использует значения из латентного пространства для генерации новых данных, которые похожи на входные.

VAE использует вероятностную модель для описания латентного пространства, что позволяет ему более точно моделировать изображения. Обучение VAE заключается в том, чтобы максимизировать границу правдоподобия, что приводит к созданию более точных и разнообразных изображений.

VAE имеет широкий спектр применений: генерация изображений, звуков и текста; улучшение качества данных; сокращение объема занимаемой данными памяти и решение других задач, требующих генерации новых данных. Одним из важных преимуществ VAE является возможность избежать повторов в создаваемых данных, что делает их более разнообразными и интересными.

В моей нейросети используется как раз VAE.

Исходный код доступен по ссылке в телеграм канале.


Пишем свой антивирус с нуля часть 1

Май 28, 2023, 10:05 - Время чтения: ~1 минут

В наше время компьютеры остаются неотъемлемой частью жизни многих людей. К сожалению, развитие технологий неизбежно приводит к появлению новых видов вредоносных программ, которые могут нанести десятки миллионов долларов ущерба как частным лицам, так и компаниям.

Решить эту проблему помогают антивирусы - программы, способные защитить ваш компьютер от вредоносных программ. Однако, вместо того чтобы покупать готовый антивирус, можно попробовать написать свой собственный.

В этой статье мы рассмотрим, как создать антивирус с нуля. Мы начнем с обзора основных типов вредоносных программ и разработки концепции антивируса.

Вот основные типы вирусов:

Вирус

  • Это программа, которая может внедряться в другие исполняемые файлы. При запуске зараженного файла он выполняет свой вредоносный код.
  • Он также может распространяться по сети или через внешние носители, такие как флеш-накопители.

Червь

  • Это автономная программа, которая способна копировать себя на другие компьютеры через сеть без участия человека или хозяина зараженной машины.
  • Черви могут использоваться злоумышленниками для создания ботнета - сети компьютеров, которые могут быть удаленно управляемыми.

Троян

  • Это программное обеспечение, которое скрывается под легитимным приложением и представляет собой скрытую угрозу.
  • Обычно трояны используются для получения несанкционированного доступа к компьютеру, шпионажа и кражи конфиденциальных данных.

Кроме этого, есть и другие типы вредоносных программ, такие как spyware (шпионские программы), adware (рекламное ПО) и многие другие. Но наиболее распространенными являются вирусы, черви и трояны.

Давайте разработаем концепцию антивируса, который будет искать вирусы с использованием методов сигнатур и хэш-сумм.

Язык программирования

Мы будем использовать язык Python, так как он обладает простым синтаксисом и удобен для работы с файловой системой. Позже перепишем его на C.

Платформа

Наш антивирус будет работать на операционных системах Windows и Linux в основном.

Функциональность

Наш антивирус будет иметь следующие функции:

  • Сканирование файлов: мы будем искать вредоносные программы в файлах по определенным путям, используя два метода - сигнатуры и хэш-суммы.
  • Добавление новых сигнатур: если антивирус не может найти совпадение, то пользователь сможет добавить новую сигнатуру для поиска.
  • Обновление базы данных: мы будем регулярно обновлять базу данных сигнатур и хэш-сумм из централизованного хранилища.
  • Уведомление о найденной угрозе: после сканирования антивирус сообщит пользователю о найденных вредоносных программах.
  • Карантин: в случае обнаружения вируса, мы поместим инфицированный файл в карантин для дальнейшего анализа или удаления.

Методы сканирования

Мы будем использовать два метода для поиска вирусов:

  • Сигнатуры: мы будем искать совпадения сигнатур - уникальными последовательностями байтов, которые характеризуют конкретную вредоносную программу.
  • Хэш-суммы: мы будем вычислять хэш-суммы файлов и сравнивать их с хэш-суммами из базы данных. Если хэш-суммы совпадают, то файл может быть заражен вирусом.

Таким образом, наш антивирус будет отслеживать вредоносные программы, используя несколько методов, что повышает его эффективность.

В следующей статье напишем простейший сканер и протестируем на самописном вирусе.