|
Звіт до лабораторної роботи №3
з курсу: «Методи та засоби стеганографії та стеганоаналізу»
на тему: «Вбудовування інформації в відеофайл»
Виконав:
Прийняв:
Львів – 2021
Мета роботи: Навчитись вбудовувати та вилучати приховане повідомлення, в відеофайл. Завдання
Розробити програму, яка реалізує метод стеганографїї для відеофайлів формату .mpeg. Програма повинна вбудовувати та вилучати приховане повідомлення. Теоретичні відомості
Найбільш популярними стандартами кодування відео є MPEG-2 і MPEG-4. Розглянемо метод вбудовування даних у відео, стиснене за стандартом MPEG-2. Стеганографічні методи, які застосовуються для вбудовування інформації в відео, стиснене за стандартом MPEG-2, мають працювати в реальному часі. Способи вбудовування ЦВЗ, які працюють в реальному часі, мають відповідати декільком вимогам і, в першу чергу, вони повинні володіти малою обчислювальною складністю. Таким чином, єдино прийнятними є методи, які вбудовують дані безпосередньо в потік стиснених даних, щоб уникнути зайвих обчислень.
Рис.1. Вбудовування / видобування ЦВЗ в розгорнуті дані
Окрім того, операція вбудовування ЦВЗ не повинна збільшувати розмір стиснених відеоданих, оскільки можуть виникнути проблеми при передачі потоку відеоданих по каналу з фіксованою швидкістю.
Перед тим, як перейти безпосередньо до обговорення способів вбудовування ЦВЗ з низькою обчислювальною складністю, необхідно коротко описати власне стандарт стиску відеоданих MPEG.
Короткий опис стандарту MPGG і можливості вбудовування даних
Основна ідея стиску за стандартом MPEG полягає у тому, що зі всього потоку даних повністю передаються лише деякі кадри, для решти ж передається лише різниця від інших кадрів.
Потік відеоданих в MPEG має ієрархічну та синтаксичну структури. Кожен рівень містить один чи більше підпорядкованих йому рівнів (рис. 2). Послідовність відеоданих розділяється на множину груп кадрів (ГК), які представляють собою множину відеокадрів, що безпосередньо слідують один за одним згідно порядку показу. Далі, кадри діляться на шари та макроблоки. Найнижчий рівень – блоковий, він складається з блоків інтенсивності і колірності макроблоку.
Алгоритм стиску MPЕG базується на гібридній схемі кодування, яка об’єднує кадрове та міжкадрове кодування послідовності відеоданих.
В межах групи кадрів часова надлишковість серед відеокадрів зменшується через застосування міжкадрового кодування з часовим передбаченням. Це значить, що одні кадри передбачаються іншими. Далі результуюча похибка передбачення кодується. В стандарті MPEG використовується три типи кадрів: I-кадри - intra-кадри, кодуються без посилань на інші кадри, містять нерухоме зображення і також використовуються для побудови інших типів кадрів; Р-кадри – передбачувані кадри, які кодуються з посиланням на попередній (з точки зору приймача) прийнятй (I) чи (Р) кадр; В-кадри двохстолронні інтерпольовані кадри, які кодуються найбільш складним чином. Такий кадр 59 может будуватися і на основі попереднього кадра, і на основі наступного кадра, і як інтерполяція між попередній та наступним кадрами.
Закодована ГК (група кадрів) завжди починається з I-кадра для забезпечення доступу до потоку відеоданих з будь-якої випадкової точки. ГК утворюється з 12 кадрів. Таким чином, при частоті 25 кадров в секунду, Iкадр приходить не рідше, ніж один раз за 0,48 секунди. Разом з ним відновлюється повна в тій чи іншій мірі ідентичність зображення.
Хід роботи
Скрипт програми для реалізації вбудовування та вилучення повідомлення
import wave
import pandas as pd
import time def start(): while True: choice = int(input("Введіть число: 1-зашифрувати 2-розшифруваати 3-завершити програму\n")) if choice == 1: encrypt() elif choice == 2: decrypt() elif choice == 3: break
data_len = int.from_bytes(wav_info[40:44], byteorder='little') # визначаємо початкову довжину файлу to_read = os.stat('txt.txt').st_size if to_read >= data_len * degree / 16: print("Забагато символів для читання") wav_file.close() return
text = open('decoded.txt', 'w')
text_mask, sample_mask = create_masks(degree) sample_mask = sample_mask data = wav_file.read(data_len) read = 0 while read < to_read: two_symbols = 0 for step in range(0, 16, degree): sample = int.from_bytes(data[:2], byteorder='little') & sample_mask data = data[2:]
two_symbols <<= degree two_symbols |= sample
first_symbol = two_symbols >> 8 text.write(chr(first_symbol)) read += 1 if to_read - read > 0: second_symbol = two_symbols & 0b0000000011111111 text.write(chr(second_symbol)) read += 1
def encode():
song = open("4.mov", mode='rb')
with open('4.mov', 'rb') as binary_file:
in_bytes = binary_file.read()
frame_bytes = bytearray(in_bytes)
print(len(frame_bytes))
string='Steganography is a really interesting'
string = string
bits = list(map(int, ''.join([bin(ord(i)).lstrip('0b').rjust(8,'0') for i in string])))
print(len(bits))
difference = {'index': [], 'difference': []}
diff_df = pd.DataFrame(data=difference)
for i in range(len(frame_bytes) - 2):
d = frame_bytes[i] - frame_bytes[i+1]
if d < 0:
d = d * -1
diff_df = diff_df.append(pd.DataFrame({"index":[i],
"difference":[d]}))
diff_df = diff_df.sort_values(by='difference', ascending=False)
key = diff_df
for i, bit in enumerate(bits):
index = int(key.iloc[i].values[0])
frame_bytes[index] = (frame_bytes[index] & 254) | bit frame_modified = bytes(frame_bytes)
with open('laba3.mov', 'wb') as fd:
fd.write(frame_modified)
song.close()
indexes = key['index'].tolist()
indexes = indexes[:len(bits)]
return indexes
for step in range(0, 16, degree): if step == 8 and not txt_symbol: break
sample = int.from_bytes(data[:2], byteorder='little') & sample_mask data = data[2:] #зміщуємо на 2 символи
bits = txt_symbol & text_mask bits >>= (16 - degree)
sample |= bits
dst_file.write(sample.to_bytes(2, byteorder='little')) txt_symbol = (txt_symbol << degree) % 65536
dst_file.write(data) dst_file.write(src_file.read())
src_file.close() dst_file.close()
return True
src_file.close() dst_file.close()
def decode(key):
song = open("laba3.mov", mode='rb')
with open('laba3.mov', 'rb') as binary_file:
in_bytes = binary_file.read()
frame_bytes = bytearray(in_bytes)
extracted = [frame_bytes[int(i)] & 1 for i in key]
string = "".join(chr(int("".join(map(str,extracted[i:i+8])),2)) for i in range(0,len(extracted),8))
decoded = string.split("###")[0] print("Sucessfully decoded: "+decoded)
song.close() def main():
print("Encode start")
key = encode()
print("Decode start")
decode(key) if __name__ == "__main__":
main()
Результати виконання програми
Рис.2. Текст для вбудовування
Рис.3. Вбудовування та видобування інформації
Рис.4. Відеофайл перед вбудовуванням інформації
Рис.5. Відеофайл з вбудованою інформацією
Рис.6. Видобутий текст
Висновок: Під час виконання даної лабораторної я навчився вбудовувати та вилучати приховане повідомлення, в відеофайл.
. скачати
|