Advertisement
warhomezx

123

Apr 14th, 2021
976
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.69 KB | None | 0 0
  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)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement