Ruby Compressor (little long)

P

Patrick Hurley

I have need to distribute applications to customers. The customers
have every right to the source code, but when it is installed we do
not want the code to be easily visible. We are not worried about super
hackers (or even moderately strong Ruby programmers :), we just do
not want our raw source code on the system calling out to be played
with by the end users.

To this end, I have developed this very simple script, which I plan on
further refining. I know there are many rough edges, but I wanted to
see if anyone else was interested in the code (or had any other
suggestions), before I went any further.

require "zlib"

@init = <<ZLIB_REQUIRE
module Kernel
alias default_require require
@@zlib_requires = {}

def zlib_requires=(zr)
@@zlib_requires = zr
end

def require(path)
return false if $".include?(path)

if @@zlib_requires.has_key(path)
eval(Zlib::Inflate.inflate(@@zlib_requires[path]))
$" << path
else
default_require path
end
end

end
ZLIB_REQUIRE

@bootstrap = <<BOOTSTRAP
require "zlib"
File.open(__FILE__, "rb") do |data|
# skip to the end
line = data.gets until line =~ /^__END__$/
f = Marshal.load(data)
eval(Zlib::Inflate.inflate(f[:init]))
Kernel.zlib_requires = f
eval(Zlib::Inflate.inflate(f[:main]))
end
__END__
BOOTSTRAP

def findrb(fname)
$:.each do |path|
fp = File.join(path, fname)
return fp if File.exists? fp
end
false
end

def compress(script)
files = {}
load(script) rescue nil

$".each do |fname|
if (File.extname(fname) == ".rb") && (fp = findrb(fname))
data = IO.read(fp)
files[fname] = Zlib::Deflate.deflate(data, Zlib::BEST_COMPRESSION)
end
end

files[:main] = Zlib::Deflate.deflate(IO.read(script), Zlib::BEST_COMPRESSION)
files[:init] = Zlib::Deflate.deflate(@init, Zlib::BEST_COMPRESSION)

File.open("compress-#{script}", "wb") do |io|
io.print @bootstrap
io.write(Marshal.dump(files))
end

# write header data - fname,
end

compress(ARGV[0])
 
P

Patrick Hurley

I havent personally used this to distribute an application, but it
sounds like it'll fit the bill:

http://www.erikveen.dds.nl/allinoneruby/index.html


Patrick said:
I have need to distribute applications to customers. The customers
have every right to the source code, but when it is installed we do
not want the code to be easily visible. We are not worried about super
hackers (or even moderately strong Ruby programmers :), we just do
not want our raw source code on the system calling out to be played
with by the end users.

To this end, I have developed this very simple script, which I plan on
further refining. I know there are many rough edges, but I wanted to
see if anyone else was interested in the code (or had any other
suggestions), before I went any further.

require "zlib"

@init = <<ZLIB_REQUIRE
module Kernel
alias default_require require
@@zlib_requires = {}

def zlib_requires=(zr)
@@zlib_requires = zr
end

def require(path)
return false if $".include?(path)

if @@zlib_requires.has_key(path)
eval(Zlib::Inflate.inflate(@@zlib_requires[path]))
$" << path
else
default_require path
end
end

end
ZLIB_REQUIRE

@bootstrap = <<BOOTSTRAP
require "zlib"
File.open(__FILE__, "rb") do |data|
# skip to the end
line = data.gets until line =~ /^__END__$/
f = Marshal.load(data)
eval(Zlib::Inflate.inflate(f[:init]))
Kernel.zlib_requires = f
eval(Zlib::Inflate.inflate(f[:main]))
end
__END__
BOOTSTRAP

def findrb(fname)
$:.each do |path|
fp = File.join(path, fname)
return fp if File.exists? fp
end
false
end

def compress(script)
files = {}
load(script) rescue nil

$".each do |fname|
if (File.extname(fname) == ".rb") && (fp = findrb(fname))
data = IO.read(fp)
files[fname] = Zlib::Deflate.deflate(data, Zlib::BEST_COMPRESSION)
end
end

files[:main] = Zlib::Deflate.deflate(IO.read(script), Zlib::BEST_COMPRESSION)
files[:init] = Zlib::Deflate.deflate(@init, Zlib::BEST_COMPRESSION)

File.open("compress-#{script}", "wb") do |io|
io.print @bootstrap
io.write(Marshal.dump(files))
end

# write header data - fname,
end

compress(ARGV[0])

I have used this and rubyscript2exe they are wonderful, but serve a
slightly different purpose. I just want to hide the code a little bit.
In our particular case installing Ruby is not a real problem.

Thanks
pth
 
P

Patrick Hurley

This:
File.open(__FILE__, "rb") do |data|
# skip to the end
line = data.gets until line =~ /^__END__$/
f = Marshal.load(data)
eval(Zlib::Inflate.inflate(f[:init]))
Kernel.zlib_requires = f
eval(Zlib::Inflate.inflate(f[:main]))
end
__END__

Can be changed to:
f = Marshal.load(DATA.read)
eval(Zlib::Inflate.inflate(f[:init]))
Kernel.zlib_requires = f
eval(Zlib::Inflate.inflate(f[:main]))
end
__END__

Thanks, I had tried that -- plus a DATA.binmode (without which it did
not work on Windows at all), but I still had a few issues, it failed
in odd ways -- I did not spend a lot of time tracking it down as I
knew that reopening the file would work -- I will check it again and
see if I can make it work or give more information on the failure.

pth
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top