warhomezx

123

Apr 14th, 2021
495
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # -*- coding: utf-8 -*-
  2. """steg_ANAL.ipynb
  3.  
  4. Automatically generated by Colaboratory.
  5.  
  6. Original file is located at
  7.    https://colab.research.google.com/drive/1jeb954KZS2bvn9AFzsW_rfEGUI8H0Mlv
  8. """
  9.  
  10. #@title
  11. import numpy as np
  12. import matplotlib.image as img
  13. import matplotlib.pyplot as plt
  14. from PIL import Image
  15. import random
  16. import string
  17.  
  18. test_message = "Among other public buildings in a certain town, which for many reasons it will be prudent to refrain from mentioning, and to which I will assign no fictitious name, there is one anciently common to most towns, great or small: to wit, a workhouse; and in this workhouse was born; on a day and date which I need not trouble myself to repeat, inasmuch as it can be of no possible consequence to the reader, in this stage of the business at all events; the item of mortality whose name is prefixed to the head of this chapter."
  19.  
  20. ### Для теста на переполнение
  21. # Генератор случайного текста
  22. def random_text_generator(size):
  23.     return ''.join(random.choices(string.ascii_letters, k=size))
  24.  
  25. # Разница между двумя строками
  26. def str_diff(s1, s2):
  27.     return sum(x != y for (x, y) in zip(s1, s2))
  28.  
  29. def str_to_bin(str):
  30.     return '{0:b}'.format(str)
  31.  
  32. def bin_to_int(bin):
  33.     return int("".join(bin), 2)
  34.  
  35. # Функция для шифрования сообщения методом LSB
  36. # img - конейнер (изображение)
  37. # message - сообщение-строка (обычная строка)
  38. # Первые max_bits бита в зашифрованном изображении - ключ (бинарное представление длинны сообщения (в битах))
  39.  
  40. def lsb_encode(img, message, max_bits=22):
  41.     encode_img = np.copy(img)
  42.    
  43.     # Ascii в бинарный формат
  44.     encoded_message = str(bin(int.from_bytes(message.encode(), 'big')))[2:]
  45.    
  46. #     print(f"Длинна сообщения: {len(encoded_message)}")
  47.    
  48.     # Создание ключа
  49.     key = str_to_bin(len(encoded_message))
  50.    
  51.     # Дополнение ключа до key_size битов
  52.     for i in range(max_bits - len(key)):
  53.         key = "0" + key
  54.    
  55. #     print(f"Ключ: {key}")
  56.    
  57.     # Процент, на сколько контейнер заполнен (в процентах)
  58.     im_size = encode_img.shape[0] * encode_img.shape[1]
  59.     cont_fullness = 100 * abs(len(key) + len(encoded_message)) / im_size
  60.    
  61. #     print(f"Заполненность контейнера(для последнего бита Red): {cont_fullness}")
  62.    
  63.     counter = 0
  64.     x = 0
  65.     y = 0
  66.    
  67.     # Записть ключа и сообщения в изображение ( с переполнением )
  68.     while(counter < len(encoded_message) + max_bits):
  69.         r                  = encode_img[x,y][0]
  70.         binary_r           = list(str_to_bin(r))
  71.         if (counter < max_bits):
  72.             binary_r[-1]   = key[counter]    
  73.         else:
  74.             binary_r[-1]   = encoded_message[counter - max_bits]
  75.  
  76.         encode_img[x,y][0] = bin_to_int(binary_r)
  77.         counter += 1
  78.        
  79.         if(y == encode_img.shape[1] - 1):
  80.             if(x == encode_img.shape[0] - 1):
  81.                 x = 0
  82.                 y = 0
  83.             else:
  84.                 x +=1
  85.                 y  =0
  86.         else:
  87.             y +=1
  88.                    
  89.     return (encode_img, cont_fullness)
  90.                
  91. def lsb_decode(decode_img, max_bits=22, isShuffle=False, shuffle_key=None):
  92.     message = ""
  93.     key = ""
  94.    
  95.     # Получить ключ
  96.     for y in range(0, max_bits):
  97.         r         = decode_img[0, y][0]
  98.         binary_r  = list(str_to_bin(r))
  99.         key      += binary_r[-1]
  100.    
  101.     key = bin_to_int(key)
  102.    
  103.     x = 0
  104.     y = 0
  105.     counter = 0
  106.    
  107.     while(counter < key + max_bits):
  108.         r = decode_img[x,y][0]
  109.         binary_r = list(str_to_bin(r))
  110.         if (counter >= max_bits):
  111.             message += binary_r[-1]
  112.         counter += 1
  113.        
  114.         if(y == decode_img.shape[1] - 1):
  115.             if(x == decode_img.shape[0] - 1):
  116.                 x = 0
  117.                 y = 0
  118.             else:
  119.                 x +=1
  120.                 y  =0
  121.         else:
  122.             y +=1
  123.            
  124.     result = ''
  125.     message = '0' + message
  126.    
  127.     for i in range (0, len(message), 8):
  128.         bin_oct = message[i: i+8]
  129.         bin_oct = int(bin_oct, 2)
  130.         try:
  131.             symbol = bin_oct.to_bytes((bin_oct.bit_length() + 7) // 8, 'big').decode()
  132.             result += symbol
  133.         except UnicodeDecodeError:
  134.             result += ''
  135.    
  136.     return result
  137.  
  138. # Читаем изображение
  139. image = img.imread("C:/lsb/cat300x300.jpg")
  140.  
  141. plt.figure(figsize = (80,50))
  142. plt.imshow(image)
  143.  
  144. output = lsb_encode(image, test_message)
  145.  
  146. plt.figure(figsize = (80,50))
  147. plt.imshow(output[0])
  148.  
  149. lsb_decode(output[0])
  150.  
  151. # Метрики (для R-канала)
  152. maxD = 0
  153. nmse = 0
  154. diff_sum_2 = 0
  155. diff_inp_2 = 0
  156. max_inp    = 0
  157. max_inp_diff    = 0
  158. diff_2     = 0
  159.  
  160. for x in range(0, image.shape[0]):
  161.     for y in range(0, image.shape[1]):
  162.         r_inp = int(image[x,y][0])
  163.         r_out = int(output[0][x,y][0])
  164.        
  165.         diff_abs  = abs(r_out - r_inp)
  166.        
  167.         diff_sum_2 += (r_inp-r_out)**2
  168.         diff_inp_2 += (r_inp)**2
  169.        
  170.         diff_2         += (r_inp - r_out)**2
  171.         max_inp_diff   = max(max_inp_diff, r_inp**2)
  172.        
  173.         maxD  = max(diff_abs, maxD)
  174.    
  175. print("maxD: ", maxD)
  176. print("nmse: ", diff_sum_2 / diff_inp_2)
  177. print("snr: ", 1 / (diff_sum_2 / diff_inp_2))
  178. print("psnr: ", max_inp_diff / diff_2)
  179.  
  180. ### Тест на ошибку при переполнении
  181. test_counts         = 30
  182. test_letter_range   = (1000, 30000)
  183. results_fullness    = []
  184. results_errors      = []
  185.  
  186. for i in range(test_counts):
  187.     letter_size       = (i + 1) * int((test_letter_range[1]) / test_counts)
  188.     test_mess         = random_text_generator(letter_size)
  189.     test_output       = lsb_encode(image, test_mess)
  190.     test_out_im       = test_output[0]
  191.     test_fullness     = test_output[1]
  192.     output_mess       = lsb_decode(test_out_im)[0:letter_size]
  193.    
  194.     diff              = str_diff(test_mess, output_mess)
  195.    
  196.     # Ошибка (0...1)
  197.     error             = ((100 * diff) / letter_size)
  198.    
  199.     results_fullness.append(test_fullness)
  200.     results_errors.append(error)
  201.    
  202.     print('\n')
  203.    
  204.     print((test_fullness, letter_size, len(output_mess), diff, error))
  205.  
  206. plt.figure(figsize = (15, 10))
  207. plt.xlabel("Заполнение контейнера (%)")
  208. plt.ylabel("Ошибка (%)")
  209. plt.plot(results_fullness,results_errors)
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×