Привет, Хабр!

Мы в ChameleonLab продолжаем строить нашу образовательную платформу по стеганографии, и сегодня хотим поделиться еще одним важным шагом на этом пути. Наша главная цель — не просто создавать инструменты, а делать сложные темы из мира кибербезопасности доступными и понятными для всех, от студентов до специалистов.

Изначально наш продукт, ChameleonLab, был написан на Python (с использованием PyQt) как мощное десктопное приложение. Но мы всегда стремились к максимальной доступности. Что может быть доступнее, чем инструмент, который работает прямо в браузере, без скачивания и установки?

Поэтому мы начали амбициозную задачу: перенести ключевые модули нашего Python-приложения в веб, используя PHP, и не просто повторить, а расширить их функционал. И сегодня мы представляем первый результат этой работы — онлайн-анализатор бит-планов изображений.

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

Что такое бит-план и почему это — «азбука» стегоанализа?

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

Каждый бит вносит свой вклад в итоговый цвет. Старшие биты (MSB) — самые "важные", они формируют контуры и основные цвета. Младшие биты (LSB) — самые "незначительные". Их изменение практически не влияет на то, как мы видим картинку. Именно эту особенность и используют для сокрытия данных: заменяя LSB-биты на биты секретного сообщения, можно "спрятать" информацию так, что визуально изображение не изменится.

Анализ бит-планов — это способ "увидеть" эти изменения. Мы берем изображение и создаем 8 новых, черно-белых картинок. Каждая из них представляет собой "срез" одного битового уровня всех пикселей:

  • Бит-план 7 (MSB): Будет похож на размытый набросок оригинала.

  • Бит-план 0 (LSB): В обычном фото должен выглядеть как случайный шум.

Если же в LSB-слое вместо хаоса вы видите узоры, текст или любые другие структурированные данные — поздравляем, вы, скорее всего, обнаружили стеганографию.

От кода к коду: Python (PyQt) vs PHP (JS)

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

Версия на Python (для десктопного приложения)
Версия на Python (для десктопного приложения)

Версия на Python (для десктопного приложения)

В нашем приложении на PyQt мы использовали всю мощь библиотеки NumPy для быстрых матричных операций. Код получается очень лаконичным и эффективным:

# Фрагмент из page_bitplane.py нашего десктопного приложения
import numpy as np

def extract_bit_plane(self, image_array, channel, bit_level):
    # Если выбран Grayscale, усредняем каналы
    if channel == "Grayscale":
        if image_array.ndim == 3:
            # Стандартная формула для преобразования в оттенки серого
            img_ch = (0.299 * image_array[:, :, 0] + 0.587 * image_array[:, :, 1] + 0.114 * image_array[:, :, 2]).astype(np.uint8)
        else:
            img_ch = image_array
    else:
        # Иначе берем нужный цветовой канал (R=0, G=1, B=2)
        img_ch = image_array[:, :, {"Red": 0, "Green": 1, "Blue": 2}[channel]]

    # Магия NumPy: побитовые операции сразу ко всему массиву
    # 1. Сдвигаем все биты вправо на `bit_level` позиций
    # 2. Оставляем только последний бит (AND 1)
    plane = np.bitwise_and(np.right_shift(img_ch, bit_level), 1)

    # Превращаем массив из 0 и 1 в черно-белое изображение (0 и 255)
    plane_scaled = (plane * 255).astype(np.uint8)
    
    # Создаем 3-канальное изображение для отображения
    return np.stack([plane_scaled] * 3, axis=-1)
Версия на JavaScript (для веб-страницы на PHP)
Версия на JavaScript (для веб-страницы на PHP)

Версия на JavaScript (для веб-страницы на PHP)

В веб-версии вся логика выполняется на стороне клиента с помощью JavaScript и HTML5 Canvas. Это позволяет сделать инструмент интерактивным без перезагрузки страницы. PHP здесь выступает в роли "обертки", которая отдает готовую страницу пользователю.

// Фрагмент из bitplane-analyzer.php
function updateBitplaneView() {
    if (!originalImageData) return;

    // Получаем данные из HTML-элементов
    const bitLevel = parseInt(slider.value, 10);
    const channel = channelSelect.value;
    const { width, height, data } = originalImageData;
    const ctxBitplane = bitplaneCanvas.getContext('2d');
    const newImageData = ctxBitplane.createImageData(width, height);
    const newPixels = newImageData.data;

    // Проходим по каждому пикселю в цикле
    // data - это одномерный массив [R, G, B, A, R, G, B, A, ...]
    for (let i = 0; i < data.length; i += 4) {
        const r = data[i], g = data[i + 1], b = data[i + 2];
        let targetValue;

        // Определяем, с каким каналом работаем
        if (channel === 'gray') {
            targetValue = Math.round(0.299 * r + 0.587 * g + 0.114 * b);
        } else if (channel === 'red') {
            targetValue = r;
        } else if (channel === 'green') {
            targetValue = g;
        } else { // blue
            targetValue = b;
        }

        // Та же логика, что и в Python, но для одного пикселя
        const color = ((targetValue >> bitLevel) & 1) * 255;
        
        // Закрашиваем пиксель в черно-белый цвет
        newPixels[i] = newPixels[i+1] = newPixels[i+2] = color;
        newPixels[i+3] = 255; // Alpha-канал (непрозрачность)
    }
    
    // Отрисовываем результат на холсте
    ctxBitplane.putImageData(newImageData, 0, 0);
}

Аналитика и сравнение подходов

Как видите, логика извлечения бита ((value >> bit_level) & 1) абсолютно идентична. Разница — в исполнении.

  • Python + NumPy — это мощь векторизации. Мы работаем со всем изображением как с единой матрицей, что идеально для тяжелых вычислений и пакетной обработки в десктопном приложении.

  • PHP + JavaScript — это интерактивность и доступность. PHP отдает "каркас", а весь анализ происходит в браузере пользователя. Перебор пикселей в цикле for на JS может быть не так быстр, как NumPy, но для одного изображения и мгновенного отклика в UI этого более чем достаточно.

Переход на веб потребовал от нас полностью переосмыслить архитектуру, но результат того стоил — теперь фундаментальный инструмент стегоанализа доступен каждому, у кого есть браузер.

Наш новый инструмент: интерактивная образовательная песочница

Перенося анализатор в веб, мы хотели сделать его не просто утилитой, а настоящей интерактивной "лабораторной работой".

Что мы реализовали в веб-версии на PHP:

  1. Мгновенная визуализация: Просто перетащите изображение в окно, и инструмент сразу покажет вам оригинал и его LSB-план (0-й бит).

  2. Интерактивное исследование: Слайдер позволяет "листать" битовые слои от 0 до 7, наглядно демонстрируя, как из хаоса младших битов рождается осмысленное изображение в старших.

  3. Анализ по каналам (RGB): Данные не всегда прячут во всех цветовых каналах. Наш инструмент позволяет исследовать каждый канал (красный, зеленый, синий) по отдельности.

  4. Автоматический помощник: Чтобы помочь новичкам, мы встроили базовый статистический анализ (Энтропия и Хи-квадрат), который автоматически делает предварительное заключение о наличии аномалий в LSB-слое.

    Слева — оригинальное изображение, справа — его LSB-план, который выглядит как случайный шум
    Слева — оригинальное изображение, справа — его LSB-план, который выглядит как случайный шум

Мы видим этот инструмент не просто как детектор, а как тренажер, который помогает развить "чувство" аномалии и понять саму суть LSB-стеганографии.

Заключение и дальнейшие планы

Переход с Python на PHP для создания онлайн-инструментов — это для нас большой и важный шаг. Он позволяет нам сделать наши разработки доступными для гораздо более широкой аудитории и интегрировать их в единую образовательную платформу. "Анализатор бит-планов" — это только начало. В будущем мы планируем перенести в веб и другие, более сложные методы анализа, добавляя к ним интерактивные объяснения и примеры.

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

Попробовать Анализатор Бит-планов изображений можно здесь: https://chalab.ru/ru/bitplane-analyzer/

Следите за нашими экспериментами и обновлениями проекта на нашем официальном сайте и Telegram-канале!

Будем рады вашим отзывам и предложениям в комментариях!

Комментарии (4)


  1. DaneSoul
    27.09.2025 23:06

    Переход с Python на PHP для создания онлайн-инструментов — это для нас большой и важный шаг.

    А что мешало сделать онлайн-инструмент на Python?
    Взяли бы Flask как микро-фреймворк и работали с привычным Python, но уже онлайн.


  1. andreymal
    27.09.2025 23:06

    весь анализ происходит в браузере пользователя

    Так а зачем здесь PHP? Отдать статическую html-страничку со столь же статическим js-кодом можно абсолютно любым веб-сервером или даже тупо на github.io закинуть


  1. MetaDone
    27.09.2025 23:06

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

    судя по тому что в файл bitplane-analyzer.php вы впихнули выдачу js кода, у вас там в этой части все смешано. может сейчас это не ощущается, но если эта часть разрастется - вы задолбаетесь разгребать. ок, в прошлой вашей статье я писал про laravel, но если для ваших целей он слишком большой - возьмите lumen, можно сказать его урезанную копию, или slim какой-нибудь.
    судя по всему у вас в команде с вебом вообще никто не работал, даже js код в отдельный файл не вынесли, не говорю уже про то чтоб использовать сборщики типа vite.

    а если посмотреть то что сейчас у вас на странице примера - там и jquery, и части которые его не используют, и bootstrap. в общем одумайтесь пока не поздно, на этом этапе цена переписывания на нормальные инструменты еще низкая


  1. Metotron0
    27.09.2025 23:06

    Кажется, это как раз тот случай, куда подходит wasm.