PageRenderTime 27ms CodeModel.GetById 40ms RepoModel.GetById 1ms app.codeStats 0ms

/resources/public/code/clojure/steganography.clj

https://github.com/strogo/nakkaya.com
Clojure | 71 lines | 56 code | 13 blank | 2 comment | 7 complexity | 5aedcc1c2e0d3d212172d73c7ff72510 MD5 | raw file
  1. (ns steganography
  2. (:use clojure.contrib.seq-utils)
  3. (:import (javax.imageio ImageIO)
  4. (java.io File)))
  5. (defn bits [n]
  6. (reverse (map #(bit-and (bit-shift-right n %) 1) (range 8))))
  7. (defn numb [bits]
  8. (BigInteger. (apply str bits) 2))
  9. (defn set-lsb [bits bit]
  10. (concat (take 7 bits) [bit]))
  11. (defn string-to-bits [msg]
  12. (flatten (map #(bits %) (.getBytes (str msg ";")))))
  13. (defn get-argb [img cord]
  14. (let [[x y] cord
  15. clr (.getRGB img x y)]
  16. [(bit-and (bit-shift-right clr 24) 0xff)
  17. (bit-and (bit-shift-right clr 16) 0xff)
  18. (bit-and (bit-shift-right clr 8) 0xff)
  19. (bit-and clr 0xff)]))
  20. (defn set-argb [img cord color]
  21. (let [[x y] cord
  22. [a r g b] color
  23. c (bit-or (bit-shift-left a 24)
  24. (bit-or (bit-shift-left r 16)
  25. (bit-or (bit-shift-left g 8) b)))]
  26. (.setRGB img x y c)))
  27. (defn match-bits-coords [bits img]
  28. (partition 2
  29. (interleave (partition 4 bits)
  30. (take (/ (count bits) 4)
  31. (for [x (range (.getWidth img))
  32. y (range (.getHeight img))] [x y])))))
  33. (defn set-pixels [img d]
  34. (doseq [[data cord] d]
  35. (let [color-bit (partition 2 (interleave (get-argb img cord) data))
  36. color (map #(let [[n b] %]
  37. (numb (set-lsb (bits n) b))) color-bit)]
  38. (set-argb img cord color))))
  39. (defn encode [fname msg]
  40. (let [img (ImageIO/read (File. fname))
  41. data (match-bits-coords (string-to-bits msg) img)]
  42. (set-pixels img data)
  43. (ImageIO/write img "png" (File. (str "encoded_" fname)))))
  44. ;;(encode "drive.png" "Attack At Down!!")
  45. (defn get-pixels [img]
  46. (map #(get-argb img %) (for [x (range (.getWidth img))
  47. y (range (.getHeight img))] [x y])))
  48. (defn split-lsb [data]
  49. (map #(last (bits %)) data))
  50. (defn decode [fname]
  51. (let [img (ImageIO/read (File. fname))
  52. to-char #(char (numb (first %)))]
  53. (loop [bytes (partition 8 (split-lsb (flatten (get-pixels img))))
  54. msg (str)]
  55. (if (= (to-char bytes) \;)
  56. msg
  57. (recur (rest bytes) (str msg (to-char bytes)))))))
  58. ;;(decode "encoded_drive.png")