#!perl

# obfuscate_js.pl
# By Jonathan Meyer <http://stej.com>
#
# This script is desinged to obfuscate javascript to the human reader but not
# to the javascript interperter.

use strict;
use Data::Dumper;

my $js_in = $ARGV[0];
my $js_out = $ARGV[1];

if( ! -e $js_in || -e $js_out )
{
  die "\nusage: obfuscate_js.pl <in file> <out file>\n";
}

open JS_IN, $js_in or die "\nError: $js_in: $!\n";

my $data = {};

while( <JS_IN> )
{
  my @line = split //;
  my $char = '';

  foreach $char( @line )
  {
  	if( $char !~ m/\n/ )
  	{
  	  push @{$data->{'in'}}, $char;
  	  $data->{'unique'}->{$char}++;
  	}
  }
}

close JS_IN;

open JS_OUT, ">$js_out" or die "\nError: $js_in: $!\n";

my $char = '';
my $count = 0;

foreach $char( sort { $data->{'unique'}->{$b} <=> $data->{'unique'}->{$a} } keys %{$data->{'unique'}} )
{
  $data->{'map'}->{$char} = $count++;
  my $escape = '';

  if( $char eq "'" || $char eq "\\" )
  {
  	$escape = '\\';
  }

  $data->{'a'} .= $escape.$char;
}

foreach $char( @{$data->{'in'}} )
{
  if( defined $data->{'b'} )
  {
    $data->{'b'} .= ',';
  }

  $data->{'b'} .= $data->{'map'}->{$char};
}

# print JS_OUT Dumper( $data );

print JS_OUT "
var a='".$data->{'a'}."';
var b=[".$data->{'b'}."];
var q='';

for( x = 0; x < b.length; x++ )
{
  q += a.charAt( b[x] );
}

eval( q );
";

close JS_OUT;

