Нет описания

steganography.cpp 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. /// \file
  2. // RAN 2014-06-10:
  3. // -- Simplified the changeMask function.
  4. // -- Simplified the masking in the EmbbedMessage function.
  5. // -- Changed EmbbedMessage so that only the pixels needed to embbed the message
  6. // are changed. Previously, all pixels were masked. This involved hardcoding a
  7. // postfix into the encodded message that repeats ASCII code 0 ten times.
  8. // RAN 2014-06-14:
  9. // -- Simplified the end of message encoding and decoding. Now it just encodes one '\0'
  10. // char at the end of the string. Also, its stops decoding when it finds a '\0'
  11. // RAN 2015-06-30
  12. // -- In the functions binaryStringToMessage and ExtractMessage, changed
  13. // string additions to character push_back.
  14. #include "steganography.h"
  15. #include <QDebug>
  16. Steganography::Steganography()
  17. {
  18. }
  19. /// \fn int cbtoi(char c)
  20. /// \~English
  21. /// \brief Converts a character bit to integer.
  22. /// \param c a character ('0' or '1'), the char that will be converted
  23. /// \return An integer 1 or 0
  24. /// \~Spanish
  25. /// \brief Convierte un bit en caracter a entero.
  26. /// \param c un caracter ('0' o '1'), el caracter que se va a convertir.
  27. /// \return Un entero 1 o 0
  28. ///
  29. int cbtoi(char c){
  30. if(c == '0') return 0;
  31. else return 1 ;
  32. }
  33. /// \fn string decToBin(int num, int pad)
  34. /// \~English
  35. /// \brief Converts an decimal number to a string in base 2.
  36. /// \param num a non-negative integer, the number that will be converted
  37. /// \param pad a non-negative integer, the number of digits
  38. /// in the resulting string
  39. /// \return A string of length pad of 0's and/or 1's.
  40. /// \~Spanish
  41. /// \brief Convierte un numero entero a una cadena de caracteres
  42. /// en base 2.
  43. /// \param num un entero positivo, el numero que se va a convertir.
  44. /// \param pad un entero positivo, el numero de digitos en la cadena de
  45. /// caracteres resultante.
  46. /// \return Una cadena de caracteres de largo pad de 0's y/o 1's
  47. ///
  48. string decToBin(int num, int pad)
  49. {
  50. int r = 0; // residue
  51. // residuo
  52. int q = -1; // quotient
  53. // cociente
  54. string b = ""; // string to containt the result
  55. // cadena de caracteres para contener el resultado
  56. while(q != 0)
  57. {
  58. r = num%2;
  59. q = num/2;
  60. num = q;
  61. if (r) b.insert(0, "1");
  62. else b.insert(0, "0");
  63. }
  64. // if letter has less than pad bits, insert 0s at the beginning until length = pad
  65. // si letter tiene menos que pad bits, insertar 0s al principio hasta que el
  66. // length = pad
  67. while(b.length() < (unsigned long) pad)
  68. b.insert(0, "0");
  69. return b;
  70. }
  71. /// \fn string messageToBinaryString(string str)
  72. /// \~English
  73. /// \brief Converts a string to a string of 1's and 0's
  74. /// that represent the ASCII codes of the characters in the original string.
  75. /// For example, "AB" results in "10000011000010".
  76. /// [-----][-----]
  77. /// ^ ^
  78. /// ASCII code of A | |
  79. /// ASCII code of B --------+
  80. ///
  81. /// \param str a string of characters to be converted to their ASCII representations
  82. /// \return A string of 0's and/or 1's.
  83. /// \~Spanish
  84. /// \brief Convierte una caena de caracteres a una cadena de 1's y 0's
  85. /// que representa el codigo ASCII de los caracteren en la cadena original.
  86. /// Por ejemplo, "AB" resulta in "10000011000010".
  87. /// [-----][-----]
  88. /// ^ ^
  89. /// Codigo ASCII de A | |
  90. /// Codigo ASCII de B --------+
  91. /// \param str una cadena de caracteres a ser convertido a su representacion ASCII
  92. /// \return Una cadena de 0's y/o 1's.
  93. ///
  94. string messageToBinaryString(string str){
  95. string binStr = "";
  96. int temp;
  97. //converting message to binary string
  98. //convirtiendo un mensaje a una cadena de caracteres binarios
  99. for(unsigned int i = 0; i<str.length(); i++)
  100. {
  101. temp = static_cast<int>(str[i]);
  102. binStr.append(decToBin(temp, bitsPerLetter));
  103. }
  104. return binStr ;
  105. }
  106. /// \fn char binStringToChar(string str)
  107. /// \~English
  108. /// \brief binStringToChar: Converts a string of 0's and 1's to an caracter
  109. /// Example, with str="0011", returns the caracter 3.///
  110. /// \param str: a string of 0's and 1's
  111. /// \return A character whose binary representation is equivalent
  112. /// to the string.
  113. /// \~Spanish
  114. /// \brief Convierte una cadena de 0's y 1's a un caracter.
  115. /// Ejemplo, con str="00000011", devuelve el caracter 3.
  116. /// \param str una cadena de 0's y 1's
  117. /// \return Un caracter ASCII cuya representacion binaria es equivalente a la cadena str.
  118. ///
  119. char binStringToChar(string str){
  120. int value = 0 ;
  121. for(unsigned int i = 0; i < str.length(); i++){
  122. value = value << 1 ;
  123. if(str[i] == '1') value = value | 1 ;
  124. }
  125. return static_cast<char>(value) ;
  126. }
  127. /// \fn int createMask(int lbits)
  128. /// \~English
  129. /// \brief Creates a mask of lbit 1's in the least significant positions.
  130. /// Example, with lbits=4, returns the integer 15, which is mask 0x1111.
  131. /// \param lbits a non-negative integer, the number of bits to set to one
  132. /// \return An integer with lbit 1's in the least signicant positions.
  133. /// \~Spanish
  134. /// \brief Crea una mascara de lbit 1's en las posiciones menos significativas.
  135. /// Ejemplo, con lbits=4, devuelve el entero 15, cuya mascara es 0x1111.
  136. /// \param lbits un entero no negativo, el numero de bits a poner en uno.
  137. /// \return Un entero con lbit 1's en las posiciones menos significativas.
  138. ///
  139. int createMask(int lbits){
  140. return (1 << lbits) - 1;
  141. }
  142. /// \fn EmbbedMessage(const QImage & origImage, QImage & newImage, string msg)
  143. /// \~English
  144. /// \brief Given an image (origImage) will create a new image (&newImage) by
  145. /// embedding the bits of the msg into the least significant bits of
  146. /// pixel colors of the original image.
  147. /// \param origImage the original image will not be modified
  148. /// \param newImage the image that is created
  149. /// \param msg the string that will be embedded
  150. /// \return By reference, the newImage is returned, containing the embedded message
  151. /// \~Spanish
  152. /// \brief Dada una imagen (origImage) creara una imagen nueva(&newImage)
  153. /// empotrando los bits de el mensaje msg en los bits menos significativos de los
  154. /// colores de la imagen original.
  155. /// \param origImage la imagen original no va a ser modificada
  156. /// \param newImage la imagen que se crea
  157. /// \param msg la cadena que va a ser empotrada
  158. /// \return Por referencia, es devuelta newImage, conteniendo el mensaje empotrado.
  159. ///
  160. void EmbbedMessage(const QImage & origImage, QImage & newImage, string msg){
  161. string binMsg ; // To store the message in binary.
  162. // Para almacenar el mensaje en binario.
  163. unsigned long msg_index = 0 ; // Will be used to pass through binStr
  164. // Sera utilizado para pasar atraves de binStr
  165. int red, green, blue ; // Will store the integer representation of the colors.
  166. // Va a guardar la representacion entera de los colores
  167. int mask = createMask(1);
  168. QRgb p;
  169. binMsg = messageToBinaryString(msg);
  170. // We will include this postfix, so that the decoder will
  171. // know when the embedded message ends. It consists of 1 char
  172. // whose ASCII is 0.
  173. // Vamos a incluir este sufijo, tal que el decodificador sepa
  174. // cuando el mensaje embedido termina. Este consiste de 1 caracter
  175. // cuyo ASCII es 0.
  176. binMsg.append(2*bitsPerLetter,'0');
  177. //for each pixel in image
  178. //por cada pixel.
  179. for(int i = 0; i < origImage.width(); i++)
  180. {
  181. for(int j = 0; j<origImage.height(); j++)
  182. {
  183. p = origImage.pixel(i,j);
  184. red = qRed(p);
  185. if(msg_index < binMsg.length()){
  186. // clear the least significant bit of the red value
  187. // limpia el bit menos significativo del valor rojo
  188. red &= ~mask;
  189. // embed the corresponding bits from the mssage
  190. // empotra el bit correspondiente del mensaje
  191. red = red | cbtoi(binMsg[msg_index]) ;
  192. msg_index += 1 ;
  193. }
  194. green = qGreen(p);
  195. if(msg_index < binMsg.length()){
  196. green &= ~mask;
  197. green = green | cbtoi(binMsg[msg_index]);
  198. msg_index += 1 ;
  199. }
  200. blue = qBlue(p);
  201. if(msg_index < binMsg.length()){
  202. blue &= ~mask;
  203. blue = blue | cbtoi(binMsg[msg_index]);
  204. msg_index += 1 ;
  205. }
  206. else{
  207. // When the message is over we stop the loops
  208. // Cuando el mensaje termina paramos los loops
  209. i = origImage.width() ;
  210. break ;
  211. }
  212. newImage.setPixel(i,j,qRgb(red, green, blue));
  213. }
  214. }
  215. }
  216. /// \fn string binaryStringToMessage(string binStr)
  217. /// \~English
  218. /// \brief Converts a string of 0's and 1's to a string
  219. /// of characters.
  220. /// Example: with str="10000011000010", returns "AB", because
  221. /// 1000001 is ASCII of A, 1000010 is ASCII of B
  222. /// \param str a string of 0's and 1's
  223. /// \return A string that contains the characters whose ASCII codes
  224. /// where specified in the input string.
  225. /// \~Spanish
  226. /// \brief Convierte una cadena de 0's y 1's a una
  227. /// cadena de caracteres.
  228. /// Ejemplo: con str = "10000011000010", devuelve "AB", porque
  229. /// 1000001 es ASCII de A, 1000010 es ASCII de B
  230. /// \param str una cadena de 0's y 1's
  231. /// \return Una cadena que contiene los caracteres cuyos codigos ASCII
  232. /// estaban especificados en la cadena de entrada.
  233. ///
  234. string binaryStringToMessage(string binStr){
  235. // YOUR CODE HERE
  236. }
  237. /// \fn string ExtractMessage(const QImage &stegoImage)
  238. /// \~English
  239. /// \brief Given an image (stegoImage) with the embedded message and the
  240. /// the number of bits embedded into each pixels colors, will
  241. /// extract the message that is hidden in the least significant
  242. /// bits of the stegoImage.
  243. /// \param stegoImage image that contains the embeded message
  244. /// \return A string containing the extracted message.
  245. /// \~Spanish
  246. /// \brief Dada una imagen (stegoImage) con un mensaje embedido y el numero
  247. /// numero de bits embedidios en cada color de los pixeles, va a extraer
  248. /// el mensaje que esta escondido en los bits menos significativos de la stegoImage
  249. /// \param stegoImage imagen que contiene el mensaje embedido
  250. /// \return Una cadena conteniendo el mensaje extraido.
  251. ///
  252. string ExtractMessage(const QImage &stegoImage){
  253. // YOUR CODE HERE
  254. }