Случайный контейнер Куттера

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 12:43, 1 июня 2017.
Open book.svg Авторство
Д. Елфимов
Согласовано: 2011

Руководство пользователя

Задача

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

Исходные файлы

1. plaintext.txt – текстовый файл, в который помещается исходный текст для сокрытия
2. output.txt – файл, в который помещается извлеченный из контейнера текст
3. RGB_before_stego.bmp – контейнер до встраивания текста
4. Stego_tmp.bmp – контейнер со встроенным текстом

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

Также заметим, что для сокрытия сообщения данным методом, необходим достаточно большой контейнер, так как мы пишем скрываемый текст не во все биты контейнера, а только в биты главной диагонали. В связи с этим не получается подавать большие входные тексты. Уже на тексте в несколько сот символов, Mathcad завис на 5 минут.

Текст выполненной программы

Основная идея этого метода, предложенного Куттером, Джорданом и Боссеном, заключается в следующем: стего встраивается в канал синего цвета (зрительная система человека наименее восприимчева именно к синему цвету) изображения, имеющего RGB кодирование путем модифкации яркости.

Стоит отметить, что алгоритм имеет статистический характер.

1. Считываем сообщение, переводим его в бинарный вид

M:= READBIN("plaintext.txt","byte") Импортируем текстовое сообщение Модуль D_B выполняет преобразование десятичного числа в двоичное.

D_B.PNG

Модуль M_b выполняет преобразование текстового файла в битовый вектор.

M b.PNG Каждый символ преобразуется с помощью ранее описанного модуля D_B и записывается в M_b.

Исходное сообщение в 10-ном варианте:

M= 0
0 84
1 104
2 105
3 115
4 32
5 109
6 101
7 116
8 104
9 111
10 100
11 32
12 100
13 111
14 101
15 ...

Исходное сообщение в 2-ном варианте:

M_b= 0
0 0
1 0
2 1
3 0
4 1
5 0
6 1
7 0
8 ...
2. Задаем константы для метода Куттера. Создаем контейнер, содержащий реализацию случайного сигнала

γ :=6 //Константа, определяющая энергию встраиваемого сигнала.Чем больше γ, тем выше

         //устойчивость встроенной информации к искажениям, однако и тем сильнее ее заметность. 
         //Установлено, что результат встраивания визуально незаметен при значениях γ меньше 0.05 

σ :=3 //Количество пикселей сверху (снизу,слева,справа) от оцениваемого пискселя Определяем количество пикселей, которые потребуются для сокрытия текста. size := rows(M_b)-1 //Определяем длину стороны side := size + 2σ //Добавляем "запасные" пиксели для декодирования OiRS Dudin LSB f row col.png //Задаем функцию, содержащую реализацию случайного сигнала, полученную с помощью функции rnd(.) R:=f(side,side) //Создаем матрицы, размером side*side, которые будут G:=f(side,side) //содержать случайные значения интенсивности для B:=f(side,side) //каждого из цветов RGB

RGB:=augment(R,G,B) //Объединяем их вместе - собираем изображение

WRITERGB("RGB_before_stego.bmp"):=RGB //Производим запись в файл для проверки правильности создания изображения Секретный бит M_bi встраивается в канал синего цвета путем модификации яркости λ(x,y)


   
Fkut(x,y,b):=round γλ(x,y)]
 

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

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

3. Занесение стего в контейнер

Модуль B_cod для записи исходного сообщения в канал синего цвета. Встраиваем каждый бит информации по главной диагонали начиная с 3й строки и 3го столбца. Получаем значение SV для каждого пикселя и записываем в B_cod. В случае если значения яркости больше 255 или меньше 0 записываем 255 и 0 соответственно:

B cod.PNG

B= 0 1 2 3 4 5 6 7 8 9 10 11
0 153 214 167 188 215 0 65 53 172 45 121 168
1 187 172 196 121 160 98 163 153 145 40 192 82
2 106 218 178 192 55 6 138 179 121 148 167 236
3 56 181 252 145 197 238 120 187 3 187 62 124
4 148 38 40 135 229 46 253 251 245 250 14 46
5 134 182 233 113 209 84 224 174 201 85 5 81
6 150 173 212 130 218 99 206 3 141 57 0 17
7 241 239 20 86 33 40 18 125 30 35 117 28
8 48 225 14 113 20 31 91 113 35 103 45 235
9 200 251 113 135 141 153 243 201 212 206 137 ...


B_cod= 0 1 2 3 4 5 6 7 8 9 10 11
0 153 214 167 188 215 0 65 53 172 45 121 168
1 187 172 196 121 160 98 163 153 145 40 192 82
2 106 218 178 192 55 6 138 179 121 148 167 236
3 56 181 252 0 197 238 120 187 3 187 62 124
4 148 38 40 135 0 46 253 251 245 250 14 46
5 134 182 233 113 209 255 224 174 201 85 5 81
6 150 173 212 130 218 99 0 3 141 57 0 17
7 241 239 20 86 33 40 18 255 30 35 117 28
8 48 225 14 113 20 31 91 113 0 103 45 235
9 200 251 113 135 141 153 243 201 212 255 137 ...


Записываем значения матрицы B_cod вместо значений B в изображение "Stego_Krest.bmp" ("Загруженный контейнер"). WRITERGB("Stego_tmp.bmp"):=augment(R,G,B_cod) Синяя цветовая состовляющая до встраивания исходного сообщения и после:

B1.PNGB cod1.PNG

4. Восстановление текста из контейнера

C1:=READRGB("Stego_tmp.bmp") Разложение на цветовые компоненты: R1:=READ_RED("Stego_tmp.bmp") G1:=READ_GREEN("Stego_tmp.bmp") B1:=READ_BLUE("Stego_tmp.bmp") Синий цвет до записи в "Stego_tmp.bmp" и после записи и разложения на компоненты:

B2.0.PNGB cod2.PNG

Модуль M_b_decod реализует алгоритм извлечения скрытого сообщения из изображения:

M b decod.PNG Зная, что сообщение записывалось по диагонали восстанавливаем его. В модуле вычисляются значения яркостей креста: пикселей сверху, снизу, слева и справа от оцениваемого пикселя сравниваются с ним по формуле. Результат сравнения записывается побитово в M_b_decod: 1 если значение яркости оцениваемого пикселя больше значений яркости в кресте, 0 в противоположном случае.

Исходное сообщение в двоичном варианте до записи и после извлечения:

M_b_decod= 0
0 0
1 0
2 1
3 0
4 1
5 0
6 1
7 0
8 0
9 0
10 0
11 1
12 0
13 1
14 1
15 ...
M_b= 0
0 0
1 0
2 1
3 0
4 1
5 0
6 1
7 0
8 0
9 0
10 0
11 1
12 0
13 1
14 1
15 ...


B D(x).PNG Переводим обратно в десятичный вид L:=B_D(M_b_decod) Сравниваем исходное сообщение M с сообщением L, полученным после извлечения из контейнера:

M= 0
0 84
1 104
2 105
3 115
4 32
5 109
6 101
7 116
8 104
9 111
10 100
11 32
12 100
13 111
14 101
15 ...
L= 0
0 84
1 104
2 105
3 115
4 32
5 109
6 101
7 116
8 104
9 111
10 100
11 32
12 100
13 111
14 101
15 ...

Записываем декодированное сообщение в файл "output.txt". WRITEBIN("output.txt", "byte",0):=L

Вывод

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

Однако при достаточно больших значениях мощности текст восстанавливается корректно. Причем даже для больших γ визуально заметить разницу между пустым контейнером и контенером с встроенным текстом невозможно (мне, во всяком случае, не удалось).

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

Файлы

Стегосообщения