Случайный контейнер. Метод Гаусса-Куттера

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

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

Задача

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

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

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

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

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

Общий смысл алгоритма Куттера.

Пусть изображение имеет RGB-кодировку. Встраивание выполняется в канал синего цвета, так как к синему цвету система человеческого зрения наименее чувствительна.

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

1. Чтение текста из файла и запись в массив.
1.1 Чтение текста из исходного файла

string_byte:=READBIN("stego.txt","byte") получили массив:

string_byte = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
0 68 111 110 39 116 32 119 111 114 114 121 33 32 66 101 32 104 ...
1.2 Чтобы избежать ошибок проведем проверку:

correct_read:=vec2str(string_byte) correct_read:="Don't worry! Be happy!"

1.3 После проверки корректности проведенной операции, преобразуем массив в битовую последовательность, более удобную в нашей работе

Bit massiv.PNG Полученный массив имеет вид:

bit_massiv = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
0 0 0 1 0 0 0 1 0 1 1 1 1 0 1 1 0 0 1 1 1 0 1 1 ...
2. Метод Куттера.
2.1 Задаем необходимые константы для реализации метода Куттера

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

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

σ :=3 //Количество пикселей сверху (снизу,слева,справа) от оцениваемого пискселя

2.2 Создаем контейнер управляемого объема, который зависит от размера нашего сообщения.Определяем количество пикселей, которые потребуются для сокрытия текста.

Вычисляем длину стороны size:=rows(bit_massiv)-1 "Запасные" пиксели для декодирования.

side:=size+2σ
2.3 Теперь создаем функцию, реальзиующую случайный сигнал (в данной задаче используетcя стандартная функция rnorm(.))

F rnorm.PNG

2.4 Создаем матрицы, содержищие значения интенсивности для каждого из цветов RGB

RED:=f_rnorm(side,side,0,255) GREEN:=f_rnorm(side,side,0,255) BLUE:=f_rnorm(side,side,0,255) Собираем изображение: RGB:=augment(Red,Green,Blue) Вид матрицы Red:

Red = 0 1 2 3 4 5 6
0 55 85 60 119 211 5 16
1 135 146 122 197 57 184 145
2 64 133 5 69 190 206 60
3 67 175 139 54 137 39 105
4 79 9 24 88 69 157 27
5 45 25 22 23 8 91 103
6 219 238 79 62 15 159 251
7 48 10 18 98 94 149 75
8 11 165 176 24 120 84 125
9 110 38 12 69 111 75 44
10 234 97 57 73 32 193 227
11 126 165 87 237 92 63 169
12 207 23 125 77 167 16 81
13 9 11 187 10 9 193 ...

Вид матрицы Green:

Green = 0 1 2 3 4 5 6
0 56 200 111 13 3 1 51
1 12 12 79 101 36 36 58
2 121 59 15 152 104 99 13
3 238 226 117 62 147 25 85
4 88 51 55 217 130 38 59
5 10 163 9 33 46 1 229
6 129 96 204 89 146 119 66
7 25 44 68 51 147 126 49
8 11 104 42 112 136 6 53
9 88 91 253 54 23 64 159
10 228 13 146 58 20 31 227
11 91 105 183 96 70 34 104
12 58 242 174 49 50 90 26
13 43 75 187 96 204 193 ...

Вид матрицы Blue:

Blue = 0 1 2 3 4 5 6
0 43 39 61 140 185 225 87
1 92 18 89 58 153 4 21
2 145 36 105 118 112 6 156
3 51 175 30 163 66 63 39
4 106 222 2 138 82 42 24
5 55 211 85 80 78 21 70
6 35 57 85 120 40 200 5
7 205 104 74 30 2 66 131
8 159 6 105 90 34 116 39
9 170 70 187 107 10 39 71
10 135 247 61 11 141 161 100
11 56 113 177 27 117 3 2
12 87 63 38 26 73 112 96
13 59 130 169 145 40 197 ...

Записываем получившееся изображение: WRITERGB("RGB_before_stego.bmp"):=RGB

2.5 Встраивание текста в контейнер.

Секретный бит M_bi встраивается в канал синего цвета путем модификации яркости:

λ(x,y)

Встраиваем бит информации в канал синего цвета. b - бит записываемой информации.

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

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

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

3. Занесение стего в контейнер
3.1 Записи исходного сообщения в канал синего цвета.

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

Messinblue.PNG

3.2 Синяя цветовая состовляющая до кодирования и после:

Blue.PNG Blue.PNG

3.3 Записываем значения матрицы mess_in_blue вместо значений Blue в изображение "RGB_before_stego.bmp"("Загруженный контейнер").

WRITERGB("Stego_cod.pmp"):=augment(Red,Green,mess_in_blue)

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

Cod1:=READRGB("Stego_cod.bmp")

4.1. Разложение на цветовые компоненты:

RED1:=READ_RED("Stego_cod.bmp") Green1:=READ_GREEN("Stego_cod.bmp") Blue1:=READ_BLUE("Stego_cod.bmp") Синий цвет до записи в "Stego_cod.bmp" и после записи и разложения на компоненты:

Blue = До
0 1 2 3 4 5
0 43 39 61 140 185 225
1 92 18 89 58 153 4
2 145 36 105 118 112 6
3 51 175 30 163 66 63
4 106 222 2 138 82 42
5 55 211 85 80 78 21
6 35 57 85 120 40 200
7 205 104 74 30 2 66
8 159 6 105 90 34 116
9 170 70 187 107 10 39
10 135 247 61 11 141 161
11 56 113 177 27 117 3
12 87 63 38 26 73 ...

Blue1.PNG

mess_in_blue = После
0 1 2 3 4 5
0 43 39 61 140 185 225
1 92 18 89 58 153 4
2 145 36 105 118 112 6
3 51 175 30 0 66 63
4 106 222 2 138 0 42
5 55 211 85 80 78 21
6 35 57 85 120 40 200
7 205 104 74 30 2 66
8 159 6 105 90 34 116
9 170 70 187 107 10 39
10 135 247 61 11 141 161
11 56 113 177 27 117 3
12 87 63 38 26 73 ...

Blue.PNG


4.2. Восстановление текста

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

Decod.PNG

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

bit_massiv = 0 1 2 3 4 5 6 7 8 9
0 0 0 1 0 0 0 1 0 1 ...
decod = 0 1 2 3 4 5 6 7 8 9
0 0 0 1 0 0 0 1 0 1 ...

Переводим обратно битовую строку в байтовую

Decod byte.PNG decod_string:=decod_byte(decod) Сравниваем исходное сообщение string_byte с сообщением decod_string, полученным после извлечения из контейнера:

string_byte = 0 1 2 3 4 5 6 7 8 9
0 68 111 110 39 116 32 119 111 114 ...
decod_string = 0 1 2 3 4 5 6 7 8 9
0 68 111 110 39 116 32 119 111 114 ...

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

Вывод

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

Файлы