require "rmagick" require "digest" class ImageUtils @@magickImg = nil @@password = "" @@message = "" @@salt = 0 @@imagickImg = nil @@width = 0 @@height = 0 @@pixel_arr = nil @@hash = nil @@rng = nil def initialize(pass, msg, uri) @@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 end h = Digest::SHA512.hexdigest(@@salt.to_s(16)) return h end def generateHash pass_h = Digest::SHA512.hexdigest(@@password) return Digest::SHA512.hexdigest(pass_h + @@salt.to_s) end def getBits(o) msg_bytes = o.unpack("c*") msg_bits = 0 for b in msg_bytes msg_bits = (msg_bits << 8) | b end return msg_bits end def getLookupTable tbl = [] # 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 = @@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 if clashes < clash_limit then break else puts "wow clashed so much sorry for breaking" exit end end tbl.push(loc) msg_bits = msg_bits >> 6 end return tbl end def getBits(o) msg_bytes = o.unpack("c*") msg_bits = 0 for b in msg_bytes msg_bits = (msg_bits << 8) | b end return msg_bits end end