Лабораторная работа 6.
Реализация метода LSB на языке программирования Python
В этой лабораторной работе обучающемуся выдаётся возможность углубиться в метод стеганографии LSB, научится проектировать код для взаимодействия с изображением и менять информацию в нём
Цель: определить алгоритм шифрования для метода LSB, написать код для шифрования и дешифрования.
Задачи:
1. Выбрать оптимальный алгоритм для шифрования.
2. Спроектировать работу кода для взаимодействия с изображением.
3. Реализовать код для шифрования.
4. Реализовать код для дешифрования.
В результате выполнения лабораторной работы студент научится редактировать изображение и скрывать сообщение в нём с помощью программы, написанной на Python
Подготовка к работе
Перед началом работы Вам необходимо скачать материал для лабораторных работ из Справочника. Скопируйте содержимое папки "Лабораторная работа 6" в удобное для Вас место. Затем в этой же папке создайте файл с расширением .py под названием "Фамилия_Группа"
Проект будет реализовываться с помощью следующего программного средства:
Python
    Алгоритм для реализации LSB метода
    Для определения алгоритма шифрования необходимо определить как устроенно изображение.
    В каждом изображении есть пиксели. Пиксели состоят из трёх основных цветов: красный, зелёный и синий (RGB), также существует палитра цветов RGBA, где буква А означает "Alpha" и определяет прозрачность пикселя. Каждый из цветов закодирован числом от 0 до 255, то есть 8 битами (рисунок 6.1).
    Рисунок 6.1
    Теперь необходимо определиться какую кодировку стоит использовать для сообщения, которое необходимо спрятать. Кодировка ASCII (таблицу можно найти в Справочнике) предлагает 256 символов, а это значить, что символы этой кодировки используют числа от 0 до 255. Кодировка ASCII идеально подходит для решения текущей задачи.
    Далее необходимо сообщение перевести в ASCII кодировку. Затем перебирается значения пикселей изображения одно за другим, после преобразования их в двоичные значения заменяется каждый наименее значимый бит на биты символов сообщения в последовательности.
    Для декодирования изображения и извлечения сообщения необходимо использовать этот же алгоритм, только в противоположную сторону: cобрать и сохранить последние биты каждого пикселя, затем разделите их на группы по 8 и преобразовать их обратно в символы ASCII.
    Задание 1. Создание алгоритма шифрования
    1. Запустите ранее созданный Python файл в любом текстовом редакторе (например Sublime 3). В нём Вы будете писать код.
    2. Теперь Вам необходимо установить необходимые библиотеки. А именно библиотеку Pillow для работы с изображением и библиотеку NumPy для математических выражений. Для установки данных библиотек введите в командную строку следущее: pip install pillow и pip install NumPy.
    3. После установки данных библиотек, Вам необходимо импортировать их в код.
    import numpy as np
    from PIL import Image
    4. Перед созданием шифрующей функции необходимо написать код для перевода изображения в NumPy массив пикселей и определения размеров изображения. Проводится проверка, является ли изображение RGB или RGBA, и записывается в переменную n, с помощью которой можно посчитать общее количество пикселей.
    def Encode(src, message, dest):
    
        img = Image.open(src, 'r') # импорт изображения
        width, height = img.size # в переменные записывается размер изображения
        array = np.array(list(img.getdata())) # создаётся массив из изображения
    
        if img.mode == 'RGB': # является ли изображение RGB
            n = 3
        elif img.mode == 'RGBA': # является ли изображение RGBA
            n = 4
        total_pixels = array.size//n # в переменную записывается общее количество пикселей
    5. Затем необходимо добавить "стоп-слово" в конце сообщения, чтобы программа знала, когда ей необходимо остановиться. Далее преобразуем это обновленное сообщение в двоичную форму и вычисляем необходимые пиксели.
    message += "СтопПрограмма" # Добавление в сообщение "Стоп-слово" 
    b_message = ''.join([format(ord(i), "08b") for i in message]) 
    req_pixels = len(b_message) # переменная, содержащая информацию о количестве необходимых символов
    6. Далее необходима проверка: достаточно ли общего количества доступных пикселей для секретного сообщения или нет. Если да, то переходим к повторению пикселей один за другим и изменению их наименее значимых битов в биты секретного сообщения до тех пор, пока не будет скрыто полное сообщение, включая "стоп-слово".
    if req_pixels > total_pixels: # если требуемых пикселей больше, чем пикселей в загруженном изображении
        print("Ошибка: необходим файл большего объёма")
    
    else:
        index=0
        for p in range(total_pixels): # цикл для записи сообщения в наименее значащие биты
            for q in range(0, 3):
                if index < req_pixels:
                    array[p][q] = int(bin(array[p][q])[2:9] + b_message[index], 2)
                    index += 1
    7. Наконец получился обновленный массив пикселей, и его можно использовать для создания и хранения в качестве целевого выходного изображения.
    array=array.reshape(height, width, n)
    enc_img = Image.fromarray(array.astype('uint8'), img.mode)
    enc_img.save(dest)
    print("Изображение успешно зашифровано") 
    Функция для шифрования сообщения в изображение готова. Получившийся код должен выглядить вот так:
    def Encode(src, message, dest):
    
        img = Image.open(src, 'r')
        width, height = img.size
        array = np.array(list(img.getdata()))
    
        if img.mode == 'RGB':
            n = 3
        elif img.mode == 'RGBA':
            n = 4
        total_pixels = array.size//n
    
        message += "СтопПрограмма"
        b_message = ''.join([format(ord(i), "08b") for i in message])
        req_pixels = len(b_message)
    
        if req_pixels > total_pixels:
            print("Ошибка: необходим файл большего объёма")
    
        else:
            index=0
            for p in range(total_pixels):
                for q in range(0, 3):
                    if index < req_pixels:
                        array[p][q] = int(bin(array[p][q])[2:9] + b_message[index], 2)
                        index += 1
    
            array=array.reshape(height, width, n)
            enc_img = Image.fromarray(array.astype('uint8'), img.mode)
            enc_img.save(dest)
            print("Изображение успешно зашифровано")
    Теперь необходимо создать функцию для дешифровки.
    Задание 2. Создание алгоритма расшифрования
    1. Для начала необходимо повторить аналогичную процедуру сохранения пикселей исходного изображения в виде массива, определить режим(RGB или RGBA) и вычислит общее количество пикселей.
    def Decode(src):
    
        img = Image.open(src, 'r')
        array = np.array(list(img.getdata()))
    
        if img.mode == 'RGB':
            n = 3
        elif img.mode == 'RGBA':
            n = 4
    
        total_pixels = array.size//n
    2. Теперь необходимо извлечь наименее значимые биты из каждого пикселя, начиная с верхнего левого края изображения, и сохранить их в группах по 8. Затем преобровать эти группы в символы ASCII, чтобы найти скрытое сообщение, пока не дойдет до "стоп-слова".
    hidden_bits = ""
    for p in range(total_pixels):
        for q in range(0, 3):
            hidden_bits += (bin(array[p][q])[2:][-1])
    
    hidden_bits = [hidden_bits[i:i+8] for i in range(0, len(hidden_bits), 8)]
    
    message = ""
    for i in range(len(hidden_bits)):
        if message[-13:] == "СтопПрограмма":
            break
        else:
            message += chr(int(hidden_bits[i], 2))
    3. Далее нужно проверить, имеется ли "стоп-слово" в изображении, если нет, то в изображении нет скрытого сообщения
    if "СтопПрограмма" in message:
        print("Скрытое сообщение:", message[:-13])
    else:
        print("Скрытое сообщения не найдено")
    Функция для расшифрования сообщения из изображения готова. Получившийся код должен выглядить вот так:
    def Decode(src):
    
        img = Image.open(src, 'r')
        array = np.array(list(img.getdata()))
    
        if img.mode == 'RGB':
            n = 3
        elif img.mode == 'RGBA':
            n = 4
        total_pixels = array.size//n
    
        hidden_bits = ""
        for p in range(total_pixels):
            for q in range(0, 3):
                hidden_bits += (bin(array[p][q])[2:][-1])
    
        hidden_bits = [hidden_bits[i:i+8] for i in range(0, len(hidden_bits), 8)]
    
        message = ""
        for i in range(len(hidden_bits)):
            if message[-13:] == "СтопПрограмма":
                break
            else:
                message += chr(int(hidden_bits[i], 2))
        if "СтопПрограмма" in message:
            print("Скрытое сообщение:", message[:-13])
        else:
            print("Скрытое сообщение не найдено")
    
    Задание 3. Создание основной функции
    1. Основная функция будет спрашивать у пользователя, какую функцию он хотел бы выполнить — шифрование или расшифрование.
    Для шифрования у пользователя запрашиваются следующие входные данные: имя исходного изображения с расширением, секретное сообщение и имя целевого изображения с расширением.
    Для расшифрования у пользователя запрашивается исходное изображение, в котором скрыто сообщение.
    def Stego():
        print("Выберите что хотите сделать")
        print("1: Зашифровать")
        print("2: Расшифровать")
    
        func = input()
    
        if func == '1':
            print("Введите путь исходного изображения")
            src = input()
            print("Введите сообщение, которое необходимо скрыть")
            message = input()
            print("Введите название файла, которое бы хотели получить")
            dest = input()
            Encode(src, message, dest)
    
        elif func == '2':
            print("Введите путь к изображению с зашифрованным текстом")
            src = input()
            Decode(src)
    
        else:
            print("Ошибка: Вы ввели несуществующий вариант")
    2. Объединив все функции Вы получите готовую программу.
    3. Сохраните получившийся .py файл.
    Задание 4. Проверка работы программы
    В папке с Вашим .py файлом находится изображение.
    1. С помощью полученной программы спрячьте в изображение любой текст.
    2. Сохраните получившиеся изображение.
    Контрольное задание.
    Ознакомьтесь с библиотекой для языка программирования Python под названием Stegano и реализуйте программу с графическим интерфейсом с помощью этой библиотеки для метода LSB.
    Ответьте на контрольные вопросы, а также отправьте преподавателю получившуюся программу из разделов 1-3 и зашифрованное изображение, программу из контрольного задания.
    Контрольные вопросы
    1. Как в программе реализуетс метод LSB?
    2. Можно ли для данной программы использовать другие кодировки?
    3. Какие минусы у такой программы?
    4. Можно ли расшифровать изображение со скрытым текстом, сделанную в другой программе?
    5. Какие еще методы можно реализовать на языке программирования Python?
    Made on
    Tilda