diff --git a/encode_image.rb b/encode_image.rb index bb10334..7a669dd 100644 --- a/encode_image.rb +++ b/encode_image.rb @@ -7,11 +7,11 @@ class EncodeImage @@utils = nil - def initialize(p, m, i) + def initialize(p, m, uri) @@password = p @@message = m - @@utils = ImageUtils.new(@@password, @@message, i) + @@utils = ImageUtils.new(@@password, @@message, uri) @@table = @@utils.generateLookupTable end @@ -32,46 +32,4 @@ 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 2b81a42..ce69924 100644 --- a/image_utils.rb +++ b/image_utils.rb @@ -1,99 +1,116 @@ -require "./pixel_image.rb" +require "rmagick" require "digest" class ImageUtils - @@magickImg = nil - @@pixelImg = nil + @@magickImg = nil - @@password = "" - @@message = "" + @@password = "" + @@message = "" + @@salt = 0 - @@hash = nil + @@imagickImg = nil - def initialize(pass, msg, i) + @@width = 0 + @@height = 0 + + @@pixel_arr = nil + + @@hash = nil + + @@rng = nil + + def initialize(pass, msg, uri) @@password = pass @@message = msg + @@salt = 0 - if msg.length > 1024 then - puts "Maximum length exceeded. Exiting." - exit - end + @@magickImg = Magick::Image.read(uri).first - @@magickImg = i + @@width = @@magickImg.columns + @@height = @@magickImg.rows - @@pixelImg = PixelImage.new(@@magickImg) + @@pixel_arr = @@magickImg.get_pixels(0, 0, @@width, @@height) - self.generateHash + @@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 getImage - return @@pixelImg + 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 + end + + h = Digest::SHA512.hexdigest(@@salt.to_s(16)) + + return h end def generateHash - h = Digest::SHA512.hexdigest(@@password) - s = @@pixelImg.getSalt + pass_h = Digest::SHA512.hexdigest(@@password) - @@hash = Digest::SHA512.hexdigest(self.interlaceHash(h, s)) + return Digest::SHA512.hexdigest(pass_h + @@salt.to_s) end - def interlaceHash(h1, h2) - puts h1 - puts h2 + def getBits(o) + msg_bytes = o.unpack("c*") - h1 = self.getBits(h1) - h2 = self.getBits(h2) - - interlaced = 0 + msg_bits = 0 - 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 + for b in msg_bytes + msg_bits = (msg_bits << 8) | b end - puts interlaced.to_s.inspect - - return interlaced.to_s + return msg_bits end - def generateLookupTable + def getLookupTable tbl = [] - 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 + # track hash classes. if too many occur during the interval, abaondon + # encoding. + clashes = 0 + clash_limit = 100 + msg_bits = self.getBits(@@message) + while msg_bits > 0 do loc = nil loop do - x = (hash_bits.to_i % @@pixelImg.getSize[:width]) - y = (hash_bits.to_i % @@pixelImg.getSize[:height]) + x = @@rng.rand(0..@@width) + y = @@rng.rand(0..@@height) loc = {"x": x, "y": y} + if !tbl.include?(loc) then + clashes = 0 + else + clashes = clashes + 1 + end - 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) + if clashes < clash_limit then + break + else + puts "wow clashed so much sorry for breaking" exit end end - hash_bits = hash_bits >> 1 - tbl.push(loc) msg_bits = msg_bits >> 6 @@ -113,4 +130,4 @@ class ImageUtils return msg_bits end -end \ No newline at end of file +end diff --git a/arty_new.png b/images/encoded/arty_new.png similarity index 100% rename from arty_new.png rename to images/encoded/arty_new.png diff --git a/clippy_new.png b/images/encoded/clippy_new.png similarity index 100% rename from clippy_new.png rename to images/encoded/clippy_new.png diff --git a/images/original/arty_2.jpg b/images/original/arty_2.jpg deleted file mode 100644 index 33febfb..0000000 Binary files a/images/original/arty_2.jpg and /dev/null differ diff --git a/runner.rb b/runner.rb index 4ef178f..df3ee09 100644 --- a/runner.rb +++ b/runner.rb @@ -1,13 +1,10 @@ -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 " + @@ -24,17 +21,21 @@ 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 -puts "Initializing EncodeImage..." - start = Time.new.to_f -em = EncodeImage.new(pass, message, img) +puts "Initializing EncodeImage..." + +iu = ImageUtils.new(pass, message, "./images/original/arty.png") + +puts "Took " + (Time.new.to_f - start).to_s + " seconds to encode... 🐱" + +=begin +em = EncodeImage.new(pass, message, "./images/original/arty.png") puts em.encode puts "Took " + (Time.new.to_f - start).to_s + " seconds to encode... 🐱" @@ -46,13 +47,12 @@ 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!"