diff --git a/images/encoded/arty_new.png b/arty_new.png similarity index 100% rename from images/encoded/arty_new.png rename to arty_new.png diff --git a/images/encoded/clippy_new.png b/clippy_new.png similarity index 100% rename from images/encoded/clippy_new.png rename to clippy_new.png diff --git a/encode_image.rb b/encode_image.rb index 7a669dd..bb10334 100644 --- a/encode_image.rb +++ b/encode_image.rb @@ -7,11 +7,11 @@ class EncodeImage @@utils = nil - def initialize(p, m, uri) + def initialize(p, m, i) @@password = p @@message = m - @@utils = ImageUtils.new(@@password, @@message, uri) + @@utils = ImageUtils.new(@@password, @@message, i) @@table = @@utils.generateLookupTable end @@ -32,4 +32,46 @@ class EncodeImage @@utils.getImage.saveImage end + + +# Need to properly sever this at some point... + + def decode +puts "Hacked in decode..." + s = @@utils.getImage.getSize + + msg_bits = 0 + + @@table.reverse.each do |loc| + pixel = @@utils.getImage.getPixel(loc[:x], loc[:y]) + msg_bits = (msg_bits << 6) | pixel.decodeBits + end + +#this trash needs to move somewhere... +puts "Try to convert the message..." + len = msg_bits & 0xffff + msg_bits = msg_bits >> 16 + + # check the padding bits.... + if (msg_bits & 255) != 0 then +puts "Padding failed scrutiny! " +puts msg_bits.to_s(2) + return false + end + + msg_bits = msg_bits >> 8 + +puts "Padding passed scrutiny..." + msg_chars = [] + + while msg_bits > 0 do + byte = msg_bits & 0xff + msg_chars.push(byte.chr) + msg_bits = msg_bits >> 8 + end + + msg = msg_chars.reverse.join + + return msg + end end \ No newline at end of file diff --git a/image_utils.rb b/image_utils.rb index ce69924..2b81a42 100644 --- a/image_utils.rb +++ b/image_utils.rb @@ -1,116 +1,99 @@ -require "rmagick" +require "./pixel_image.rb" require "digest" class ImageUtils - @@magickImg = nil + @@magickImg = nil + @@pixelImg = nil - @@password = "" - @@message = "" - @@salt = 0 + @@password = "" + @@message = "" - @@imagickImg = nil + @@hash = nil - @@width = 0 - @@height = 0 - - @@pixel_arr = nil - - @@hash = nil - - @@rng = nil - - def initialize(pass, msg, uri) + def initialize(pass, msg, i) @@password = pass @@message = msg - @@salt = 0 - @@magickImg = Magick::Image.read(uri).first - - @@width = @@magickImg.columns - @@height = @@magickImg.rows - - @@pixel_arr = @@magickImg.get_pixels(0, 0, @@width, @@height) - - @@hash = self.generateHash - - # convert hex string into an int to store for making the lookup table - @@rng = Random.new(@@hash.to_i(16)) - - puts self.getLookupTable.inspect - end - - def getPixel(x, y) - loc = (y*@@width) + x - - return @@pixel_arr[loc] - end - - def getSalt - for x in 0..@@width-1 - for y in 0..@@height-1 - pix = self.getPixel(x, y) - - @@salt = @@salt + (pix.red/512) - @@salt = @@salt + (pix.green/512) - @@salt = @@salt + (pix.blue/512) - end + if msg.length > 1024 then + puts "Maximum length exceeded. Exiting." + exit end - h = Digest::SHA512.hexdigest(@@salt.to_s(16)) + @@magickImg = i - return h + @@pixelImg = PixelImage.new(@@magickImg) + + self.generateHash + end + + def getImage + return @@pixelImg end def generateHash - pass_h = Digest::SHA512.hexdigest(@@password) + h = Digest::SHA512.hexdigest(@@password) + s = @@pixelImg.getSalt - return Digest::SHA512.hexdigest(pass_h + @@salt.to_s) + @@hash = Digest::SHA512.hexdigest(self.interlaceHash(h, s)) end - def getBits(o) - msg_bytes = o.unpack("c*") + def interlaceHash(h1, h2) + puts h1 + puts h2 - msg_bits = 0 + h1 = self.getBits(h1) + h2 = self.getBits(h2) + + interlaced = 0 - for b in msg_bytes - msg_bits = (msg_bits << 8) | b + while h1.to_i > 0 and h2.to_i > 0 do + interlaced = (interlaced << 1) | (h1 & 1) + h1 = h1 >> 1 + interlaced = (interlaced << 1) | (h2 & 1) + h2 = h2 >> 1 + +# puts interlaced +# puts h1 +# puts h2 end - return msg_bits + puts interlaced.to_s.inspect + + return interlaced.to_s end - def getLookupTable + def generateLookupTable tbl = [] - # track hash classes. if too many occur during the interval, abaondon - # encoding. - clashes = 0 - clash_limit = 100 + hash_bits = @@pixelImg.getBits(@@hash) + msg_bits = @@pixelImg.getBits(@@message) + + # gross, but pad in the 24 bits that will become the msg length + # and padding bits... + msg_bits = msg_bits << 24 - msg_bits = self.getBits(@@message) - while msg_bits > 0 do loc = nil loop do - x = @@rng.rand(0..@@width) - y = @@rng.rand(0..@@height) + x = (hash_bits.to_i % @@pixelImg.getSize[:width]) + y = (hash_bits.to_i % @@pixelImg.getSize[:height]) loc = {"x": x, "y": y} - if !tbl.include?(loc) then - clashes = 0 - else - clashes = clashes + 1 - end - if clashes < clash_limit then - break - else - puts "wow clashed so much sorry for breaking" + break if !tbl.include?(loc) + hash_bits = hash_bits >> 1 + + if hash_bits <= 0 then + puts + puts "wow too much data" + puts "leftover bits: " + msg_bits.to_s(36) exit end end + hash_bits = hash_bits >> 1 + tbl.push(loc) msg_bits = msg_bits >> 6 @@ -130,4 +113,4 @@ class ImageUtils return msg_bits end -end +end \ No newline at end of file diff --git a/images/original/arty_2.jpg b/images/original/arty_2.jpg new file mode 100644 index 0000000..33febfb Binary files /dev/null and b/images/original/arty_2.jpg differ diff --git a/runner.rb b/runner.rb index df3ee09..4ef178f 100644 --- a/runner.rb +++ b/runner.rb @@ -1,10 +1,13 @@ +require "rmagick" + require "./image_utils.rb" require "./encode_image.rb" +img = Magick::ImageList.new "./images/original/arty.png" + #srand(12345) pass = "my_password" - message = "This is the message that I would like to save please " + "and thank you also I love you? AND apostrophe's, and " + "also some commas somewhere hiding around here, It's " + @@ -21,21 +24,17 @@ message = "This is the message that I would like to save please " + "are going even further. further than anyone believed " + "`~!@\#\{$%^&*()-_=+\][}{';:'}]} Wooow. 123456789!1234" + "56789! so put 15 more??????400!" +#message = "tests" puts message.length puts message puts -start = Time.new.to_f - puts "Initializing EncodeImage..." -iu = ImageUtils.new(pass, message, "./images/original/arty.png") +start = Time.new.to_f -puts "Took " + (Time.new.to_f - start).to_s + " seconds to encode... 🐱" - -=begin -em = EncodeImage.new(pass, message, "./images/original/arty.png") +em = EncodeImage.new(pass, message, img) puts em.encode puts "Took " + (Time.new.to_f - start).to_s + " seconds to encode... 🐱" @@ -47,12 +46,13 @@ result = em.decode puts result -=end - puts "Took " + (Time.new.to_f - start).to_s + " seconds to decode... 🐱" if message == result then puts "WOW THEY MATCH! 🐱🐱🐱🐱🐱🐱🐱🐱" end +exit +puts + puts "Done!"