Arg, scooped! I was working on this <i>exact</i> same thing! :D<p>Since you've beat me to it, let me offer up a couple additional tricks you might want to use. If you want to make this completely independent of browser API's, you can eliminate the dependence on window.location (or atob/btoa as the sla.ckers.org poster did).<p>Trick #1 is to get the letter "S".<p>You can extract this from the source code of the String constructor, but you want to be careful to make this as portable as possible. The ES spec doesn't mandate much about the results of Function.prototype.toString, although it "suggests" that it should be in the form of a FunctionDeclaration. In practice you can count on it starting with [whitespace] "function" [whitespace] [function name]. So how to eliminate the whitespace?<p>For this, we can make use of JS's broken isNaN global function, which coerces its argument to a number before doing its test. It just so happens that whitespace coerces to NaN, whereas alphabetical characters coerce to 0. So isNaN is just the predicate we need to strip out the whitespace characters. So we can reliably get the string "S" from:<p>[].slice.call(String+"").filter(isNaN)[8]<p>Of course, to get isNaN you need the Function("return isNaN")() trick, and you know how the rest of the encoding works.<p>Trick #2 then lets you get any lowercase letter, in particular "p".<p>For this, we can make use of the fact that toString on a number allows you to pick a radix other than 2, 8, 10, or 16. Again, the ES spec doesn't <i>mandate</i> this, but in practice it's widely implemented, and the spec does say that if you implement it its behavior needs to be the proper generalization of the other radices. So we can get things like:<p>(25).toString(26) // "p"<p>(17).toString(18) // "h"<p>(22).toString(23) // "m"<p>and other hard-to-achieve letters.<p>But once you've got "p", you're home free with escape and unescape, as you said in your post.<p>Dave
I made a little script to extract the original javascript from a script obfuscated with OP's tool (<a href="http://patriciopalladino.com/files/hieroglyphy/" rel="nofollow">http://patriciopalladino.com/files/hieroglyphy/</a>).<p>And because I felt it was appropriate, I created this extraction script <i>in</i> an obfuscated form!<p>Use this to extract obfuscated scripts: <a href="http://pastebin.com/raw.php?i=Q9TB4wEF" rel="nofollow">http://pastebin.com/raw.php?i=Q9TB4wEF</a><p>Just save your obfuscated script in a variable called "original" and then run my code. It'll return with the extracted script.<p>Oh, and it won't work on itself. That's because I didn't use the obfuscation tool to create it. I made it mostly by hand: <a href="http://pastebin.com/9LBWCSJs" rel="nofollow">http://pastebin.com/9LBWCSJs</a>
So, basically Javascript is just a superset of an esolang that contains itself.<p><a href="http://esolangs.org/wiki/Main_Page" rel="nofollow">http://esolangs.org/wiki/Main_Page</a><p>(Especially true if you're developing with a Javascript interpreter hosted in Javascript. Really, it's esolangs all the way down.)
If you like reducing programs to basic expressions you should read into SKI combinator calculus and the X combinator.
Here is a paper that describes the construction of an efficient X combinator[1].
Reading the paper gave me insight in how simple yet powerful combinatory logic is.<p>[1]www.staff.science.uu.nl/~fokke101/article/combinat/combinat.ps
I evalled all pieces of Javascript of <30 characters in Rhino, takes 1 minute on my laptop. 4219 possible values, after stripping out some really uninteresting stuff. Doesn't seem to contain anything interesting, unfortunately.<p><a href="http://pastebin.com/CM5ac6Xi" rel="nofollow">http://pastebin.com/CM5ac6Xi</a>
Looks cool, but I couldn't make it work.<p>I went to <a href="http://patriciopalladino.com/files/hieroglyphy/" rel="nofollow">http://patriciopalladino.com/files/hieroglyphy/</a> and put in a script "alert(1);". This provided me with a script of about 8300 characters.<p>I created a web page to execute the script:<p><pre><code> <body onload="
[][(![]+[])[!+[] ...
</body>
</code></pre>
Firebug reports:<p><pre><code> ReferenceError: Unescaee is not defined.
</code></pre>
Looks like it's having trouble picking up a "p".
Some of you may also enjoy aaencode by Yosuke Hasegawa:<p><a href="http://utf-8.jp/public/aaencode.html" rel="nofollow">http://utf-8.jp/public/aaencode.html</a><p>Encode any JavaScript program to Japanese style emoticons (^_^)<p>And of course jjencode:<p><a href="http://utf-8.jp/public/jjencode.html" rel="nofollow">http://utf-8.jp/public/jjencode.html</a><p>(hint: have a look at "palindrome")
This guy did it with 6 characters by removing {}. But it lacks the detailed description available in this post.<p>EDIT: I didn't check properly. You only use {} for a minor detail.<p><a href="http://utf-8.jp/public/jsfuck.html" rel="nofollow">http://utf-8.jp/public/jsfuck.html</a>
I remember something like this a few years ago. They were using it for XSS.
<a href="http://news.ycombinator.com/item?id=1153383" rel="nofollow">http://news.ycombinator.com/item?id=1153383</a>