I consider this brittle because:

  1. It has to be in a file to work.
  2. In its file, it has to be one long line, and it has to be the first line.
  3. It relies on a particular implementation of crypt.
$gkh=open+0;$_=$WptYp=<0>;while(s*(..)(.{8})**){$keG.=crypt$2,$1}$WptYp^=$keG;$WptYp=~y%\040-\x7f%%cd;print$WptYp=~m~(J.{3})~,"\n"

I didn't do much to obscure what this code does, but here's a short description:

  1. It opens itself and reads itself into a string (both $_ and $WptYp).
  2. It takes chunks of ten non-newline characters at a time and puts them through crypt with the first two as salt, and it concatinates all the results in $keG.
  3. It XORs its own text ($WptYp) with the crypted text ($keG).
  4. It filters out characters outside the printable range.
  5. It prints the first match of four characters beginning with "J".

Since crypt is a one-way function, there's no direct way to create a program like this that generates a particular text. To make this JAPH, I wrote a program that generated random instances of a format like the above and test whether they produced a match. The parts it varied were the variable names and the delimiters on m, s, and y. It found the above after 1.4 million tries. It found one (on my home node) to print "kyle" after 6.8 million tries.

I wanted to make one that would produce the whole phrase, "Just another Perl hacker", but it ran all weekend on eight computers and never found one. The pattern it was trying to match (reproduced below) was based on Leet to make it easier, but it still never got one.

sub wanted { my $space = qr/[_.`' \t]/; my $u = qr/[uv]/; my $s = qr/[s5z2\$]/; my $t = qr/[t7+]/; my $n = qr/[n^]/; my $o = qr/[o0p]/; my $h = qr/[h#]/; my $e = qr/[e3&]/; my $r = qr/[r2]/; my $p = qr/[p?9]/; my $l = qr/[l1|]/; my $c = qr/[c<({\[]/; return qr/j$u$s$t $space [a'4@^]$n$o$t$h$e$r $space $p$e$r$l $space $h[a4@^]($c[k]$e|x$o)$r/x; }

After I started this, I wondered if there was something similar already here, and I found liverpole's signature. I'd be interested in other instances.

Replies are listed 'Best First'.
Re: Brute force JAPH
by liverpole (Monsignor) on Feb 05, 2007 at 14:49 UTC
    Hi kyle,

    I wrote an obfuscation that does something similar.  It was actually the inspiration that made me base my signature on the same idea.

    It's a good (and, I believe, seldom-used) mechanism for obfuscations, partly because you can't know what the output will be until you run it.  perl -MO=Deparse program.pl doesn't help a bit!

    Update  You could also simply do ...

    die+substr+(crypt+qw/DTA4u=Dh tO/),2,4

    ... or something equally simple :)


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

      you can't know what the output will be until you run it.

      Yes! That's a better way of saying what I like about it.

      You could also simply do ...

      Yes, that's a lot simpler, and it obviously requires the same brute force approach to produce. Still, I really like the idea of having it use itself to produce its output, but I'm not sure why. If I weren't shooting for that specifically, generation would have been easier. An early version did not vary the delimiters, but there was too much static text producing the same results from iteration to iteration.