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 угроз

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


Стрибог

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

"Стрибог" - российская хеш-функция, разработанная для обеспечения криптографической защиты информации. Она использует 512-битное состояние и 10 раундов вычислений, что обеспечивает надежность и безопасность данных. Функция использует различные методы суммирования и конструкцию Миагути - Пренели для защиты от атак.

"Стрибог" был подвергнут криптоаналитическим атакам, и результаты проведенного конкурса свидетельствуют о его высокой степени стойкости. Быстродействие "Стрибога" исследовалось и сравнивалось с другой хеш-функцией ГОСТ Р 34.11-94, и оно оказалось вполне удовлетворительным.

Значимость "Стрибога" подтверждается его использованием в реализации системы ДЭГ на выборах президента России. Это свидетельствует о высокой доверенности и надежности данной хеш-функции.


Смена раскладки клавиатуры Kubuntu

Октябрь 22, 2023, 01:10 - Время чтения: ~1 минут

Параметры системы -> Устройства ввода -> клавиатура -> дополнительно-> Switching to another layout -> выбираем удобные сочетания клавиш для смены языка ввода


Установка ssl сертификата lets encrypt на nginx в Ubuntu 20.04 и выше

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

Для начала обновимся:

sudo apt update && sudo apt upgrade

Установим все необходимое:

sudo apt install certbot nginx python3-certbot-nginx

Далее настроим certbot:

certbot certonly

Вас попросят выбрать конфигурацию и ввести email, а позже и домен. А потом просто запросим сертификат:

sudo certbot run --nginx

Сменить пароль Ubuntu linux

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

Сменить пароль можно консольной командой:

sudo passwd root

Ошибка PIP: If you wish to install a non-Debian-packaged Python package

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

Ошибка:

If you wish to install a non-Debian-packaged Python package,
create a virtual environment using python3 -m venv path/to/venv.
Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
sure you have python3-full installed.

If you wish to install a non-Debian packaged Python application,
it may be easiest to use pipx install xyz, which will manage a
virtual environment for you. Make sure you have pipx installed.

See /usr/share/doc/python3.11/README.venv for more information.

Или:

Если вы хотите установить Python-пакет, который не является пакетом Debian, создайте виртуальное окружение с помощью команды python3 -m venv путь/к/виртуальному/окружению. Затем используйте путь/к/виртуальному/окружению/bin/python и путь/к/виртуальному/окружению/bin/pip. Убедитесь, что у вас установлен пакет python3-full.

Если вы хотите установить Python-приложение, которое не является пакетом Debian, может быть проще использовать команду pipx install xyz, которая управляет виртуальным окружением для вас. Убедитесь, что у вас установлен пакет pipx.

Дополнительную информацию можно найти в файле /usr/share/doc/python3.11/README.venv.

Обойти это ограничение можно следующим образом:

sudo rm /usr/lib/python3.11/EXTERNALLY-MANAGED

Также хотел бы предложить подписаться на мой телеграм-канал

Если у вас есть какие-либо вопросы или нужна дополнительная помощь, не стесняйтесь спрашивать!


Почему using namespace std - плохо?

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

Используя пространства имен, мы можем явно указать, из какого пространства имен мы хотим использовать определенный символ. Например, в коде std::cout, std является пространством имен, а cout - символом из этого пространства имен, представляющим стандартный поток вывода. Использование ключевого слова using namespace std позволяет нам обращаться к символам из пространства имен std без явного указания этого пространства имен каждый раз. Однако, это также может привести к проблемам. Например, если мы имеем два различных пространства имен, каждое со своим символом info, и мы используем using namespace для обоих пространств имен, то возникает конфликт имён. Компилятор не знает, из какого пространства имен мы хотим использовать info, и может возникнуть неоднозначность. Чтобы избежать таких проблем, хорошей практикой является указывать пространство имен перед каждым символом или использовать только необходимые символы из пространства имен с помощью оператора разрешения области видимости ::. Также стоит избегать использования using namespace в глобальной области видимости в заголовочных файлах, чтобы не добавлять символы из пространства имен в глобальную область видимости всего проекта.

Более простым языком я рассказал об этом в своем телеграм канале: https://t.me/Aren_et_adventures/12