Initial catchat commit.
This commit is contained in:
commit
8b30fe923c
9 changed files with 460 additions and 0 deletions
1
README.md
Normal file
1
README.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
🐱
|
||||
BIN
arty_new.png
Normal file
BIN
arty_new.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1 MiB |
51
decode_image.rb
Normal file
51
decode_image.rb
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
class DecodeImage
|
||||
@@password = ""
|
||||
@@utils
|
||||
|
||||
def initialize(pass, image)
|
||||
@@password = pass
|
||||
|
||||
# initializing utils...
|
||||
@@utils = ImageUtils.new(@@password, image)
|
||||
|
||||
@@table = @@utils.generateLookupTable
|
||||
end
|
||||
|
||||
def 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
|
||||
88
encode_image.rb
Normal file
88
encode_image.rb
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
class EncodeImage
|
||||
@@password = ""
|
||||
@@message = ""
|
||||
|
||||
@@img = nil
|
||||
|
||||
@@utils = nil
|
||||
|
||||
|
||||
def initialize(p, m, i)
|
||||
@@password = p
|
||||
@@message = m
|
||||
|
||||
@@utils = ImageUtils.new(@@password, @@message, i)
|
||||
|
||||
@@table = @@utils.generateLookupTable
|
||||
end
|
||||
|
||||
def encode
|
||||
msg_bits = @@utils.getImage.getBits(@@message)
|
||||
msg_bits = msg_bits << 8 | 0
|
||||
msg_bits = msg_bits << 16 | @@message.length
|
||||
|
||||
s = @@utils.getImage.getSize
|
||||
|
||||
original_img = @@utils.getImage.fuzzImage
|
||||
|
||||
@@table.each do |loc|
|
||||
pixel = @@utils.getImage.getPixel(loc[:x], loc[:y])
|
||||
msg_bits = pixel.encodeBits(msg_bits)
|
||||
end
|
||||
|
||||
# for x in 0..s[:width]-1
|
||||
# for y in 0..s[:height]-1
|
||||
|
||||
# loc = {"x": x, "y": y}
|
||||
# if @@table.include? loc then
|
||||
# pixel = @@utils.getImage.getPixel(x, y)
|
||||
# msg_bits = pixel.encodeBits(msg_bits)
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
|
||||
@@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
|
||||
81
image_utils.rb
Normal file
81
image_utils.rb
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
require "./pixel_image.rb"
|
||||
require "digest"
|
||||
|
||||
class ImageUtils
|
||||
@@magickImg = nil
|
||||
@@pixelImg = nil
|
||||
|
||||
@@password = ""
|
||||
@@message = ""
|
||||
|
||||
@@hash = nil
|
||||
|
||||
def initialize(pass, msg, i)
|
||||
@@password = pass
|
||||
@@message = msg
|
||||
|
||||
if msg.length > 400 then
|
||||
puts "Maximum length exceeded. Exiting."
|
||||
exit
|
||||
end
|
||||
|
||||
@@magickImg = i
|
||||
|
||||
@@pixelImg = PixelImage.new(@@magickImg)
|
||||
|
||||
self.generateHash
|
||||
end
|
||||
|
||||
def getImage
|
||||
return @@pixelImg
|
||||
end
|
||||
|
||||
def generateHash
|
||||
h = Digest::SHA512.hexdigest(@@password)
|
||||
s = @@pixelImg.getSalt
|
||||
|
||||
merge_to_i = h + s
|
||||
|
||||
@@hash = Digest::SHA512.hexdigest(h+s)
|
||||
end
|
||||
|
||||
def generateLookupTable
|
||||
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
|
||||
|
||||
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])
|
||||
|
||||
loc = {"x": x, "y": y}
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
return tbl
|
||||
end
|
||||
end
|
||||
BIN
images/original/arty.png
Normal file
BIN
images/original/arty.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 579 KiB |
61
pixel.rb
Normal file
61
pixel.rb
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
class Pixel
|
||||
@mp = nil
|
||||
|
||||
@r = 0
|
||||
@g = 0
|
||||
@b = 0
|
||||
|
||||
def initialize(mp)
|
||||
@mp = mp
|
||||
|
||||
@r = @mp.red
|
||||
@g = @mp.green
|
||||
@b = @mp.blue
|
||||
end
|
||||
|
||||
def randomize
|
||||
@r = ((@r >> 2) << 2) | rand(4)
|
||||
@g = ((@g >> 2) << 2) | rand(4)
|
||||
@b = ((@b >> 2) << 2) | rand(4)
|
||||
end
|
||||
|
||||
def getMagickPixel
|
||||
@mp.red = @r
|
||||
@mp.green = @g
|
||||
@mp.blue = @b
|
||||
return @mp
|
||||
end
|
||||
|
||||
def getPixelBits()
|
||||
bits = 0
|
||||
|
||||
bits = (bits << 8) | @r
|
||||
bits = (bits << 8) | @g
|
||||
bits = (bits << 8) | @b
|
||||
|
||||
return bits
|
||||
end
|
||||
|
||||
def encodeBits(bits)
|
||||
@r = ((@r >> 2) << 2) | (bits & 3)
|
||||
bits = bits >> 2
|
||||
|
||||
@g = ((@g >> 2) << 2) | (bits & 3)
|
||||
bits = bits >> 2
|
||||
|
||||
@b = ((@b >> 2) << 2) | (bits & 3)
|
||||
bits = bits >> 2
|
||||
|
||||
return bits
|
||||
end
|
||||
|
||||
def decodeBits
|
||||
bits = 0
|
||||
|
||||
bits = (bits << 2) | (@b & 3)
|
||||
bits = (bits << 2) | (@g & 3)
|
||||
bits = (bits << 2) | (@r & 3)
|
||||
|
||||
return bits
|
||||
end
|
||||
end
|
||||
128
pixel_image.rb
Normal file
128
pixel_image.rb
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
require "./pixel.rb"
|
||||
|
||||
class PixelImage
|
||||
@@magickImg = nil
|
||||
|
||||
@@pixels = []
|
||||
|
||||
def initialize(i)
|
||||
@@magickImg = i
|
||||
@@width = @@magickImg.columns
|
||||
@@height = @@magickImg.rows
|
||||
|
||||
self.buildPixels
|
||||
end
|
||||
|
||||
def buildPixels
|
||||
tmp_pixels = @@magickImg.get_pixels(0, 0, @@width, @@height)
|
||||
|
||||
for x in 0..@@width-1
|
||||
@@pixels[x] = []
|
||||
for y in 0..@@height-1
|
||||
@@pixels[x][y] = Pixel.new(tmp_pixels.pop)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Only used for generating truly random base images
|
||||
def randomPixels
|
||||
for x in 0..@@width-1
|
||||
@@pixels[x] = []
|
||||
for y in 0..@@height-1
|
||||
pixel = 0
|
||||
|
||||
r = rand(256)
|
||||
g = rand(256)
|
||||
b = rand(256)
|
||||
|
||||
pixel = (pixel << 8) | r
|
||||
pixel = (pixel << 8) | g
|
||||
pixel = (pixel << 8) | b
|
||||
@@pixels[x][y] = Pixel.new(pixel)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def saveImage
|
||||
puts "and the mult is..."
|
||||
|
||||
puts @@width * @@height
|
||||
|
||||
pixel_array = []
|
||||
|
||||
for x in @@pixels.reverse.each do
|
||||
for y in x.reverse.each do
|
||||
pix = y.getMagickPixel
|
||||
|
||||
pixel_array.append(pix.red)
|
||||
pixel_array.append(pix.green)
|
||||
pixel_array.append(pix.blue)
|
||||
end
|
||||
end
|
||||
|
||||
new_img = Magick::Image.new(@@width, @@height)
|
||||
|
||||
|
||||
new_img.import_pixels(0, 0, @@width, @@height, "RGB", pixel_array)
|
||||
|
||||
new_img.write("arty_new.png")
|
||||
end
|
||||
|
||||
def getPixels
|
||||
return @@pixels
|
||||
end
|
||||
|
||||
def getPixel(x, y)
|
||||
return @@pixels[x][y]
|
||||
end
|
||||
|
||||
def setPixelBits(x, y, bits)
|
||||
@@pixels[x][y] = Pixel.new(bits)
|
||||
end
|
||||
|
||||
def getSize
|
||||
return {"width": @@width, "height": @@height}
|
||||
end
|
||||
|
||||
def fuzzImage
|
||||
for x in 0..@@width-1 do
|
||||
for y in 0..@@height-1 do
|
||||
@@pixels[x][y].randomize
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def getSalt
|
||||
salt = 0
|
||||
|
||||
for x in 0..@@width-1
|
||||
for y in 0..@@height-1
|
||||
pix = @@pixels[x][y].getPixelBits
|
||||
|
||||
salt = salt << 6 | ((pix >> 2) & 0b111111)
|
||||
pix = pix >> 8
|
||||
salt = salt << 6 | ((pix >> 2) & 0b111111)
|
||||
pix = pix >> 8
|
||||
salt = salt << 6 | ((pix >> 2) & 0b111111)
|
||||
pix = pix >> 8
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
h = Digest::SHA512.hexdigest(salt.to_s(16))
|
||||
|
||||
return h
|
||||
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
|
||||
50
runner.rb
Normal file
50
runner.rb
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
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 " +
|
||||
"gonna be pushing it a bit here... 1234567 let's huck " +
|
||||
"some more stuff in here to bump it to 255. Wow. We " +
|
||||
"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 em.encode
|
||||
puts "Took " + (Time.new.to_f - start).to_s + " seconds to encode... 🐱"
|
||||
puts
|
||||
|
||||
start = Time.new.to_f
|
||||
|
||||
result = em.decode
|
||||
|
||||
puts result
|
||||
|
||||
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!"
|
||||
Loading…
Add table
Add a link
Reference in a new issue