Advertisement
Guest User

Untitled

a guest
Dec 18th, 2014
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.30 KB | None | 0 0
  1. # coding: utf-8
  2.  
  3. import base64
  4. import Image
  5. import sys
  6.  
  7. """ This is a simple steganography script
  8. Base64-encoded message will be hidden in a image file
  9. """
  10.  
  11. def bin6bits(n):
  12. """ Convert given decimal number to 6-bit binary
  13. >>> bin6bits(10)
  14. '001010'
  15. """
  16. return bin(n)[2:].zfill(6)
  17.  
  18. def c2b(c):
  19. """ Convert given character to 6-bit binary
  20. >>> c2b('0')
  21. '000000'
  22. """
  23. code = ord(c)
  24. ascii_range = lambda head, tail: ord(head) <= code and code <= ord(tail)
  25. if ascii_range('0', '9'):
  26. return bin6bits(code - ord('0'))
  27. elif ascii_range('A', 'Z'):
  28. return bin6bits(code - ord('A') + 10)
  29. elif ascii_range('a', 'z'):
  30. return bin6bits(code - ord('a') + 10 + 26)
  31. elif c == '+':
  32. return bin6bits(62)
  33. elif c == '/':
  34. return bin6bits(63)
  35.  
  36. def hide(c, r, g, b):
  37. """ Hide given character to last-2bits of r/g/b each
  38. """
  39. cb = c2b(c)
  40. rb, gb, bb = bin6bits(r), bin6bits(g), bin6bits(b)
  41. rb = rb[:-2] + cb[0:2]
  42. gb = gb[:-2] + cb[2:4]
  43. bb = bb[:-2] + cb[4:6]
  44. return int(rb, 2), int(gb, 2), int(bb, 2)
  45.  
  46. def encode(src_txt, src_img, dst_img):
  47. """ Create new image which has hidden message(src_txt)
  48. """
  49. txt = open(src_txt).read()
  50. b64_txt = base64.b64encode(txt)
  51.  
  52. img = Image.open(src_img)
  53. w, h = img.size
  54.  
  55. n = len(b64_txt.replace('=',''))
  56. n_padding = len(b64_txt) - n
  57. d = len(str(n))
  58.  
  59. if (2 + d + n) > w * h:
  60. print 'Picture size is too small, or text length is too long...'
  61. quit()
  62.  
  63. pxl = img.load()
  64.  
  65. # The first pixel shows the number of padding (=)
  66. r, g, b = pxl[0, 0]
  67. pxl[0, 0] = hide(str(n_padding), r, g, b)
  68.  
  69. # The second pixel indicates digit number of text's length
  70. r, g, b = pxl[1, 0]
  71. pxl[1, 0] = hide(str(d), r, g, b)
  72.  
  73. # From the third pixel, write the text length
  74. for i in range(2, d+2):
  75. c = str(n)[i-2]
  76. y = i / w
  77. x = i % w
  78. r, g, b = pxl[x, y]
  79. pxl[x, y] = hide(c, r, g, b)
  80.  
  81. # After the length information, memorize the text
  82. for i in range(n):
  83. c = b64_txt[i]
  84. if c == '=': break
  85. y = (2 + d + i) / w
  86. x = (2 + d + i) % w
  87. r, g, b = pxl[x, y]
  88. pxl[x, y] = hide(c, r, g, b)
  89.  
  90. img.save(dst_img, 'PNG')
  91. print '[success] saved as %s\n%d message length + %d padding' % (dst_img, n, n_padding)
  92.  
  93. def main():
  94. encode('source.txt', 'sushi.png', 'yogurt.png')
  95.  
  96. if __name__ == '__main__':
  97. import doctest
  98. doctest.testmod()
  99. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement