I thought of adding more bits by using other whitespace characters, but
in the end stuck with space and tab, since everything will render them
as whitespace (whereas almost any other whitespace I tried showed up as
garbage in one editor/reader or another). Also, I didn't use linefeed
nor carriage return, since non-binary transmission from one system to
another could potentially break the file (ie, eol conversion).

Anyway, here's my solution.  I tried to keep it short and simple but
should still be easily understood.


#!/usr/bin/env ruby

Bits  = '01'
Blank = " \t"

def shebang(f)
    f.pos = 0 unless f.gets =~ /^#!/
end

def confuse(fname)
    File.open(fname, File::RDWR) do |f|
        shebang f
        f.pos, data = f.pos, f.read
        f.puts "require '#{File.basename($0, '.*')}'"
        f.write data.unpack('b*').join.tr(Bits, Blank)
        f.truncate f.pos
    end
end

def clarify(fname)
    File.open(fname, File::RDONLY) do |f|
        shebang f
        f.gets # skip require 'whiteout'
        eval [f.read.tr(Blank, Bits)].pack('b*')
    end
end

if __FILE__ == $0
    ARGV.each { |fname| confuse fname }
else
    clarify($0)
end