[HN Gopher] JSFuck (2012)
       ___________________________________________________________________
        
       JSFuck (2012)
        
       Author : tomrod
       Score  : 354 points
       Date   : 2021-09-26 00:21 UTC (22 hours ago)
        
 (HTM) web link (www.jsfuck.com)
 (TXT) w3m dump (www.jsfuck.com)
        
       | userbinator wrote:
       | I remember encountering this as one of the layers of a heavily
       | obfuscated script (with DRM-related purposes, not
       | surprisingly...) many years ago --- fortunately, there's a
       | corresponding unobfuscator for it:
       | 
       | https://enkhee-osiris.github.io/Decoder-JSFuck/
       | 
       | The same script also featured both of these equally-amusing
       | obfuscations:
       | 
       | http://utf-8.jp/public/aaencode.html
       | 
       | http://utf-8.jp/public/jjencode.html
        
         | thunderbong wrote:
         | Didn't work with the example on JSFuck page
        
       | blueprint wrote:
       | > It does not depend on a browser, so you can even run it on
       | Node.js.
       | 
       | wow this is exactly what I wanted!
        
       | ollyfg wrote:
       | I probably deserve to get downvoted to oblivion for this but...
       | I've deployed JSFuck in production!
       | 
       | We wanted to obfuscate this bit of code, to make life just a
       | little bit harder for reverse engineers. We made this huge
       | function where we pretty much passed in all our application
       | state, and it would run this JSFuck code, and spit out a token.
       | We even made a few tweaks to the code so that you couldn't just
       | reverse it back into JS with something like https://enkhee-
       | osiris.github.io/Decoder-JSFuck/.
       | 
       | Performance was surprisingly alright, and it has never hit an
       | environment where it couldn't execute. All in all, a fun few
       | hours setting it up, and I haven't had to touch it since!
        
         | maple3142 wrote:
         | I think you ultimately need to do something like
         | Function(code)() in JSFuck, so it is always possible to remove
         | the final function call and get the `code` directly.
        
           | [deleted]
        
         | zemnmez wrote:
         | makes me sad to hear that :( I will say, as a reverse engineer,
         | that javascript minifiers like closure compiler will optimize
         | almost all obfuscation out, and the rest you can usually
         | translate to a form which it can understand and then it will do
         | the rest.
         | 
         | The effect of obfuscation is not what you expect. It seems like
         | it moves the whole difficulty up, but it only moves up the
         | floor. By doing so it tends to remove all the signals that
         | would warn non-experts of security issues. Remove the
         | obfuscation and then you have all the catastrophic security
         | issues that have accumulated in there like treasures in an
         | egyptian king's tomb https://zemnmez.medium.com/how-to-hack-
         | the-uk-tax-system-i-g...
        
           | veb wrote:
           | Thanks for the link to that blog post, really interesting!
        
           | raspasov wrote:
           | Do you consider Google Closure sufficiently good obfuscation?
        
             | zemnmez wrote:
             | I think closure compiler's 'obfuscation' is an incidental
             | part of its minification passes.
        
               | raspasov wrote:
               | Got it. Thank you.
               | 
               | I've been using the Google Closure compiler for many
               | years with advanced and every time I look at the code
               | output I'm like "there's no way in a 100 years I would be
               | able to de-obfuscate back to my own code to a great
               | extent". But I don't specialize in reverse engineering,
               | so I might be missing something big.
        
               | stjohnswarts wrote:
               | Expecting obfuscation to increase security is a fool's
               | errand. However expecting it to cut down on re-use of
               | your code then it will no doubt work.
        
           | createunderrate wrote:
           | Obfuscation is like locking your front door. It won't stop
           | anyone who is dedicated, but it might stop someone who isn't.
        
           | woojoo666 wrote:
           | While I think itcs bad to use obfuscation to hide security
           | holes, I do think obfuscation has it's uses. If there's
           | reasons to make data private, then there's reasons to make
           | execution private as well. Not to mention, it was recently
           | proved that indistinguishable obfuscation is possible, so I'm
           | not sure how useful de-obfuscation tools will be in the
           | future
        
             | jstanley wrote:
             | But you don't make data private by obfuscating it and then
             | passing it to people you don't trust.
             | 
             | You make data private by not giving it to people you don't
             | trust, or by encrypting it and not giving the key to people
             | you don't trust.
        
               | woojoo666 wrote:
               | By "making data private" I meant encryption
        
           | 0xFF0123 wrote:
           | Really enjoyed that blog post, thanks for linking it! How
           | long would you say actually finding those two issues took?
           | The attack surface must've been fairly large, but I guess
           | intuition helps.
        
           | slig wrote:
           | I'm curious: can you can undo the obfuscation of JScrambler
           | and Obfuscator.io easily? Some time ago I tried to run both
           | through Closure Compiler, but it was way harder than I
           | thought would be.
        
             | zemnmez wrote:
             | JScrambler I actually did de-obfuscate to bypass some very
             | significant bot detection a few years ago, but it took a
             | bit more doing -- it uses ES6 features IIRC so I had to
             | transpile it down to ES5 via babel first, but it worked OK
             | after that.
             | 
             | has a pretty good crack at obfuscator.io, too:
             | https://closure-
             | compiler.appspot.com/home#code%3D%252F%252F%...
             | 
             | That's the example from the site. "console.log('Hello
             | world')" gets deobfuscated to "console[a(482)]("Hello
             | World!");"
        
               | stavros wrote:
               | > That's the example from the site. "console.log('Hello
               | world')" gets deobfuscated to "console[a(482)]("Hello
               | World!");"
               | 
               | That does _not_ look deobfuscated to me.
        
               | ByteJockey wrote:
               | Anyone familiar with JS is going to have some really good
               | guesses at what a(482) is in this case.
               | 
               | And, even if you don't, you can always call a(482)
        
               | stavros wrote:
               | Yes, but "obfuscated" means "To make so confused or
               | opaque as to be difficult to perceive or understand".
               | That's obfuscated, not deobfuscated.
        
           | MrQuincle wrote:
           | Makes me think of what might deter a reverse engineer and
           | then this most awesome youtube talk on psychological warfare
           | by Chris Domas
           | 
           | https://youtu.be/HlUe0TUHOIc
           | 
           | It's so good.
        
         | Dylan16807 wrote:
         | Did you have a legitimate reason to make things harder for
         | reverse engineers?
        
           | hungryforcodes wrote:
           | Why are you reverse engineering my code in the first place?
        
             | 8note wrote:
             | Because it's broken for my usecase, and I need to do
             | something slightly different on the webpage
        
               | hungryforcodes wrote:
               | You shouldn't have access to it -- it's on my private
               | servers doing stuff for me. How did you get it?
               | 
               | I think the problem with this thread is people think I am
               | writing browser code, or code that is going to be shared
               | on GitHub.
               | 
               | I am not.
               | 
               | Also I'm only half joking as I've indicated with the "/s"
               | below.
        
               | Dylan16807 wrote:
               | > You shouldn't have access to it -- it's on my private
               | servers doing stuff for me. How did you get it?
               | 
               | Well thanks for chiming in about a completely unrelated
               | topic from website javascript. My comment wasn't getting
               | downvoted until your slapfight with oauea blew up.
        
               | hungryforcodes wrote:
               | Specifically from the web page:
               | 
               | "It does not depend on a browser, so you can even run it
               | on Node.js."
        
               | howaboutnope wrote:
               | That wasn't a top level question though, it was a
               | question to a commenter saying " _We wanted to obfuscate
               | this bit of code, to make life just a little bit harder
               | for reverse engineers._ " That you obfuscate code nobody
               | other than you can even access is completely irrelevant
               | as a reply to that question.
        
               | hungryforcodes wrote:
               | So then you should ignore the entire thread and move on.
               | Why are you wasting time on this?
        
               | lillesvin wrote:
               | > You shouldn't have access to it -- it's on my private
               | servers doing stuff for me. How did you get it?
               | 
               | Seems like the logical solution would be to restrict
               | access to it then, rather than obfuscate it making it
               | harder for yourself to maintain. But hey, you do you.
        
               | hungryforcodes wrote:
               | At the bottom of the thread I explain the intention is to
               | protect against unauthorized access.
               | 
               | I also wouldn't obviously edit the obfuscated production
               | code, so it wouldn't really be a problem.
        
             | TeMPOraL wrote:
             | Because you gave it to me to run it. I want to know what is
             | it exactly that I'm running.
             | 
             | Also, why do you mind me doing that?
        
               | hungryforcodes wrote:
               | No, I didn't give it to you to run. It's explained below
               | if you read the whole thread.
        
               | [deleted]
        
             | oauea wrote:
             | To figure out what it's doing, obviously.
        
               | hungryforcodes wrote:
               | Please STOP that.
        
               | cybernautique wrote:
               | I'll make you a promise: if your code never ends up on my
               | machine, I will never try to reverse it.
               | 
               | Otherwise, all bets are off.
        
               | hungryforcodes wrote:
               | Why would I put it on YOUR machine? It's my code. Don't
               | hack my servers, or all bets are off. /s
        
               | quickthrower2 wrote:
               | JS is often (but not always) transmitted from the server
               | to execute on the client machine
        
               | hungryforcodes wrote:
               | You've never heard of NodeJS?
        
               | quickthrower2 wrote:
               | (but not always) <~ this includes nodejs
        
               | cybernautique wrote:
               | Friend, I'd love to come to an agreement that your code
               | won't end up on my machine. I'm buying beers when we get
               | together.
        
               | squeaky-clean wrote:
               | Don't request it then :p
        
               | cybernautique wrote:
               | If it's not part of any service that's marketed to me, I
               | won't. However, if some vendor wants to run code on my
               | machine, I _will_ be inspecting it.
        
               | oauea wrote:
               | No thanks. Anything you submit to run on my machine is
               | fair play :-)
        
               | hungryforcodes wrote:
               | This code should never run on your machine. :P
        
               | oauea wrote:
               | Then why are you obfuscating it or even worried about
               | people deobfuscating it? This thread is about Javascript.
        
               | hungryforcodes wrote:
               | Dude, I write financial applications in Node. Node IS
               | javascript.
               | 
               | These applications run on the back end. Some of the API
               | facing VMs have been attacked and so to be honest I've
               | configured them so that if someone did get access to
               | them, they wouldn't find much. Maybe just some API keys I
               | can invalidate. Although I probably won't do it -- an
               | obfuscator like this could be very handy here.
        
               | Madeindjs wrote:
               | Did you give a try of Deno. This is a JavaScript runtime
               | but it produce a single binary. This would make sense in
               | your case because it can be harder to inspect it.
        
         | classichasclass wrote:
         | I understand the frustration, but as someone having to debug
         | browser bugs with JavaScript edge cases, minified (and in this
         | case ultra-obfuscated) JS is hell on earth to untangle and I
         | wish people wouldn't.
        
           | int0x2e wrote:
           | Just making sure - you're using js source maps, right? The
           | minifaction should be adding significant pain in your
           | debugging process.
        
             | robocat wrote:
             | Source maps are used for anti-debugging:
             | https://www.perimeterx.com/tech-blog/2019/javascript-anti-
             | de...
        
               | mikeyjk wrote:
               | That blog is horrific on mobile
        
             | uryga wrote:
             | IME, code on prod rarely ships with a sourcemap. and as far
             | as i can tell, GP is talking about other people's minified
             | code, not something where they control the build process
        
         | IncRnd wrote:
         | For someone to reverse your code, all they need to do is run it
         | through this.                 https://enkhee-
         | osiris.github.io/Decoder-JSFuck/
        
           | tdeck wrote:
           | I think you missed this sentence from the comment you're
           | replying to:
           | 
           | > We even made a few tweaks to the code so that you couldn't
           | just reverse it back into JS with something like
           | https://enkhee-osiris.github.io/Decoder-JSFuck/.
        
         | z3t4 wrote:
         | A further obfuscation you could also compress it and have the
         | app unpack itself.
         | 
         | eJztVUESwyAIfAs3GJ60w/+/UZKiUUwzztT20OZiwgIbWJXAwARTmMAX02qRr0o
         | 9Vu02xRmwgKUPTzHv0weu8bGtZFhKyKSnTK0Z/parAJ/VI5WyXp7Uo/HYNc3qNc
         | hzKWBACnpCK3uj3N1Quvs6qCSJ4Gvah+++VT9/q3AlWLH5Pg3/cRqO94lR5SM5T
         | 6rDKSelDOUKC0+EzQ36l5N/zR7lDqti9Xjsj3U71f4AduQBlR9rUg==
        
         | SNosTrAnDbLe wrote:
         | If you can use the decoder, the reverse engineers will use the
         | same, no?
        
         | catchaway_4v93a wrote:
         | Interesting. I can definitely relate. As an author of a
         | proprietary application written in web technologies, it's easy
         | to be envious of compiled languages.
         | 
         | This is my recipe for minification:
         | 
         | 1. Apply a convention where all class properties and methods
         | have to end with a trailing underscore (it's trivial to make an
         | Eslint rule to enforce it)
         | 
         | 2. Use 2 minification tools in following order: Closure
         | Compiler (simple optimizations mode), then Terser for best
         | output.
         | 
         | 3. Configure Terser mangle.properties.regex: /_$/
         | 
         | 4. If it's a desktop app, use Bytenode for Node.js processes
         | (cannot be used for the renderer)
         | 
         | I also consider creating a tool to mangle string literals if
         | they match a pattern. I.e. all string literals in the code that
         | end with __ would be mangled. The benefit is that all internal
         | event names and what not will not be visible.
         | 
         | Yep, it's not going to hide it completely, but it's just that
         | much harder to RE and understand when there is pretty much
         | nothing descriptive in plain English left in the code (except
         | error messages and third party libraries).
         | 
         | Also I had this idea a few years earlier in a previous
         | application where I did not use a module bundler. It was good
         | old ES5 with files merged with Gulp and using prototype
         | pattern. For those who do not know, prototype pattern is
         | essentially like a class, but it's properties and methods do
         | not have to be enclosed in one block. I did not implement it,
         | but theoretically, it would be possible to create a mixer that
         | would take all these prototype classes and their properties and
         | create an output where all properties and methods from all
         | classes would be output in a completely random order, all mixed
         | together. Though looking back, it's probably not such a bright
         | idea, as it would be possible to create an AST program that
         | would reorder the methods back in place.
        
         | throwawayboise wrote:
         | Please tell me who you work for and the website where this is
         | deployed so I can avoid both.
        
           | dang wrote:
           | Please don't cross into personal attack on HN.
           | 
           | https://news.ycombinator.com/newsguidelines.html
        
         | google234123 wrote:
         | You must have changed it a lot, this seems to produces 100s of
         | kb of obfuscate code for with just a tiny input.
        
         | richardfey wrote:
         | Talk about security by obscurity!
        
         | userbinator wrote:
         | I think I might've actually analysed the code you're
         | describing.
         | 
         |  _We even made a few tweaks to the code so that you couldn 't
         | just reverse it back into JS_
         | 
         | This is why a lot of us keep our tools private... an old
         | tradition of the cracking scene going back decades to the 80s.
         | Think of things like IDA/Hexrays and Ghidra, then realise the
         | most prolific crackers had similar private tools they had
         | written many years before those appeared.
        
           | richardfey wrote:
           | But once better tools have been published, why not show what
           | you did?
        
           | tonyedgecombe wrote:
           | >This is why a lot of us keep our tools private
           | 
           | How ironic, that you want to open up other peoples code but
           | keep your own hidden.
        
             | stjohnswarts wrote:
             | The world is a complex place. It's not just open source vs
             | closed source.
        
             | laumars wrote:
             | Different motives. Think of it like encryption: when
             | someone finds a weakness in a cypher people will generally
             | move onto a new cypher that's harder to crack. The
             | difference here is the purpose of writing those tools isn't
             | to improve security, it's to break code open. So keeping
             | these tools hidden keeps them effective.
        
             | spijdar wrote:
             | Not really ironic or related. The privacy here is, well,
             | keeping the tools entirely private -- no distribution or
             | highly limited distribution, not obscuring their function.
             | 
             | Irony would be applying obfuscation or other DRM protection
             | techniques to tools intended to de-obfuscate/reverse
             | engineer which are then distributed/sold. This is fairly
             | common in commercial reverse engineering solutions,
             | although I don't think the irony of the cat and mouse game
             | is lost on the authors in that case...
        
             | bsza wrote:
             | why not - after all, none of the open source licenses say
             | that you must actually _distribute_ the program, they only
             | say that you should also include the source code if doing
             | so.
        
       | sharmin123 wrote:
       | The Best And Easiest Ways To Protect Yourself From Hackers:
       | https://www.hackerslist.co/the-best-and-easiest-ways-to-prot...
        
       | txt wrote:
       | Very cool. Reminds me of a few years back when I was writing apps
       | for facebook..along with there fan pages. They had there own
       | markup language 'fbml' and 'fbjs'. The app was executed in a
       | sandbox inside an iframe, which you could add as a tab on a fan
       | page as well. A few times I broke thru there sandbox, allowing me
       | to run any xss on page load, even on the fan page...it grabbed
       | there token and added friends, invited a random number or friends
       | to a fan page, likes fan pages, then post a status update...all
       | random, nd it would base it on how many friends the user had.
       | Anyway, a big problem was other developers stealing my code thnx
       | to it being JS...So I ended up using every bug in JS like this,
       | to confuse. I made a function that would pull element
       | names/type/src etc, then used that as a alphanumeric definition.
       | So my source had no spelt out names...on top of using JS
       | hacks..then finally obfuscating. I rmbr the last time I did this
       | and released it into the wild..it was patched up by FB in the
       | morning after it sent to a security researcher who posted on his
       | popular site for his audience to reverse engineer, which they did
       | in a few hours...everything but the few lines that was passed to
       | fb's sandbox that returned the broken code which enabled me to
       | run the xss.... Gooooood times...javascript is fun#!
        
       | baybal2 wrote:
       | Decyphering something like these was a part of so many job
       | interviews
        
         | tyingq wrote:
         | I'm mystified why an interviewer would want to know _" has this
         | guy memorized that adding two empty arrays in javascript nets
         | 'empty string'?"_
        
       | dang wrote:
       | Past threads:
       | 
       |  _JSFuck - esoteric JavaScript_ -
       | https://news.ycombinator.com/item?id=9479834 - May 2015 (38
       | comments)
       | 
       |  _JSFuck - Write any JavaScript with 6 Characters: []()!+_ -
       | https://news.ycombinator.com/item?id=6379732 - Sept 2013 (71
       | comments)
       | 
       |  _JSFuck []()+ Use only 6 characters to write any JavaScript_ -
       | https://news.ycombinator.com/item?id=4421848 - Aug 2012 (1
       | comment)
        
         | tomrod wrote:
         | You're awesome dang. Thanks for the context.
        
           | macintux wrote:
           | This is a feature not everyone stumbles upon, but if you
           | follow the _2nd_ link called "past" on the page, the one
           | under the headline, it performs a search for you for previous
           | discussions.
           | 
           | Dang has his own tool, but it's handy when he hasn't done the
           | search yet.
           | 
           | (The _1st_ such link, at the very top, emulates previous
           | days' front page.)
        
       | hsuduebc2 wrote:
       | I love this.
        
       | oblosys wrote:
       | Hmm, this could actually be useful:
       | 
       | [][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[
       | ]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[
       | ])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]
       | +!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[
       | +!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+(
       | [][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!
       | +[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][
       | (![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]
       | )[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+
       | !+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[
       | ]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[
       | ])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[
       | ]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+
       | []]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+
       | []]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]
       | ]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]
       | +[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]
       | [[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])
       | [+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(!
       | []+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+
       | (!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+
       | [])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]
       | +[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])
       | [+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]
       | ]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]
       | ]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!!
       | []+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+
       | []]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])
       | [+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+
       | (!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]
       | ]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[]
       | )[+!+[]]+(![]+[])[!+[]+!+[]])()([][(![]+[])[+[]]+(![]+[])[!+[]+!+
       | []]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+
       | []+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![
       | ]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[
       | +[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(
       | !![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]
       | +(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[
       | ]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]
       | +(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]](
       | (!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]
       | +[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+([]+[])[(![]+[])[+[
       | ]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!!
       | []+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][
       | (![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]
       | +[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(
       | ![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+
       | (!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+
       | [])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]]+((
       | ![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+
       | []]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[
       | !+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+
       | []]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]]
       | +([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+
       | []+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+([][[]]+[])[+!
       | +[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+
       | []+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[
       | ]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+(!![]+
       | [])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+
       | !+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[
       | ]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[
       | ]+!+[]]+[+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]
       | +[!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]
       | +!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+
       | []]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[
       | !+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[+!+[]]+[!+[]+!+[]]+([][[]]+[
       | ])[+[]]+(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+
       | []])+[])[+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[
       | ]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+
       | !+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+([][[]]+[])[!+[]+
       | !+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]]+[+!+[]]+(!![]+[])[+[]]+[
       | +!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+
       | !+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[
       | ]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]
       | +!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+
       | [!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[
       | +!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]
       | +(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]]+[+[]]+(!![]+[])[+[]]+[+!
       | +[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]
       | ]+[!+[]+!+[]]+[+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+
       | !+[]])[(![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+[+!+[]]+[+!+[]]))[(!
       | ![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[
       | +!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(!
       | []+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!
       | +[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(
       | !![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[
       | ]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]
       | +[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])
       | [!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!
       | +[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])
       | [+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+
       | []]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+
       | !+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!
       | +[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+
       | []+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([
       | ][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]
       | ]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]
       | +[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!!
       | []+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[
       | ]+!+[]+!+[]+[+!+[]])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!
       | +[]+[+[]]]+(!![]+[])[+[]]]((!![]+[])[+[]])[([][(!![]+[])[!+[]+!+[
       | ]+!+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]
       | +[][[]])[+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[
       | ]+!+[]]]()+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+
       | []+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([![]]+[][
       | []])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]](([][(![]+[])[+[]]+(![]+[])[
       | !+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]
       | +[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[
       | ]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!!
       | []+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+
       | !+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[
       | ])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!
       | +[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[
       | ]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+
       | !+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+
       | ([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(![]+[+[]])[
       | ([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[
       | ])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+
       | [])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]
       | ]+(![]+[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]]+![]+(![]+[+[]])[([![]]
       | +[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[
       | ]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+
       | []+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]
       | +[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]])()[([][(![]+[])[+[]]+(![]+[]
       | )[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+
       | (!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+
       | [])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[
       | ]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[
       | +[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]
       | +!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!
       | +[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[
       | ]]]((![]+[+[]])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[
       | ])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![
       | ]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[]
       | )[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]])+[])[+
       | !+[]])+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]
       | +!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[
       | +!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+
       | [])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[
       | +[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[
       | +[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+
       | []]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]
       | ]]()[+!+[]+[!+[]+!+[]]])())
        
         | IncRnd wrote:
         | I bet you feel Rick Rolled. I have NoScript! I'm glad you
         | didn't write something like
         | location="http://y2u.be/dQw4w9WgXcQ
        
         | lsllc wrote:
         | I think I see Steve Jobs' face there ... (if I stare at it long
         | enough)
         | 
         | /s
         | 
         | (well done btw)
        
       | tombert wrote:
       | This reminds me of a blog post about using pure lambda calculus
       | for whiteboard problems [1].
       | 
       | I'm always fascinated by these "minimum viable language
       | projects", since I think they sort of get into a fundamental
       | concept: what _is_ computing exactly?
       | 
       | [1] https://www.jtolio.com/2017/03/whiteboard-problems-in-
       | pure-l...
        
         | hsn915 wrote:
         | This is not about minimal computing. It's just using
         | Javascript's weir rules in unexpected ways.
        
       | jedbrown wrote:
       | This is honestly quite disappointing compared to prior art.
       | https://metacpan.org/pod/Acme::EyeDrops
        
         | azalemeth wrote:
         | That is genuinely amazing. I miss perl.
        
       | odyssey7 wrote:
       | This is fascinating.
        
       | kyeb wrote:
       | This is horrifying.
        
         | chronogram wrote:
         | I thought it's really cool instead.
        
           | yjftsjthsd-h wrote:
           | Sometimes there is no distinction:)
        
       | esoprogramming wrote:
       | Interview with its creator, Martin Kleppe, here:
       | https://esoteric.codes/blog/interview-with-martin-kleppe
        
         | yesenadam wrote:
         | Thank you! Only a couple of pages, but he mentions many
         | fascinating things.
        
       | egberts1 wrote:
       | I don't bother with obfuscated JavaScript codes; I hook the equal
       | operators for all strings and arrays then look for URL patterns.
       | L33t!
        
       | fnord77 wrote:
       | how is this "educational"? it's about as readable as hexadecimal
       | machine code. What's the lesson?
        
         | eyelidlessness wrote:
         | If you want a sincere answer: it provides a huge state space of
         | how unexpected input can produce much more unexpected results.
         | If nothing else it's educational about how you _really_
         | shouldn't trust input, and _REALLY_ should scrutinize how it's
         | used.
        
         | everyone wrote:
         | It demonstrates how awful javascript is.
        
           | TimTheTinker wrote:
           | Flexible !== awful
        
             | justin_oaks wrote:
             | JavaScript can certainly be awesome, but the tricks that
             | JSFuck relies on aren't "flexible". They're things that
             | make you say "Wat?"
             | 
             | https://www.destroyallsoftware.com/talks/wat
        
               | fctorial wrote:
               | If your code adds two arrays together, there's something
               | seriously wrong with your code. It isn't that different
               | from divide by zero error.
        
             | phaedryx wrote:
             | I noticed that you had to use !== instead of != because the
             | comparison operators in JavaScript are awful :D
        
               | TimTheTinker wrote:
               | Touche :)
               | 
               | Though I'd still argue that the presence of both
               | `==`/`!=` and `===`/`!==` is somewhat more indicative of
               | flexibility than awfulness.
        
             | [deleted]
        
             | Dylan16807 wrote:
             | I'd say about half the interactions this relies on fall in
             | the 'trash' category. It doesn't mean javascript is trash,
             | but it has a lot of trash in it.
        
       | micahbule wrote:
       | I actually had a chance to meet Martin once during JSConf in
       | Singapore back in November 2014. Very cool guy with a
       | hysterically fucked up humor with JS.
       | 
       | I mean... http://aem1k.com/world speaks for itself.
       | 
       | JSFuck was included in his presentation back then and boy did it
       | inspire me to do more JS. Here we are, a little under 7 years
       | later, still in the JS world.
        
       | abacadaba wrote:
       | This is amazing!
        
       | axegon_ wrote:
       | To be fair it doesn't make it any less readable than normal js...
        
       | usui wrote:
       | I don't understand how this works. I've seen brainfuck before,
       | but not truly understood it. How is it possible to open up a new
       | tab, paste the encoded form, and have working JavaScript?
        
         | city41 wrote:
         | Here's the decoder ring:
         | https://github.com/aemkei/jsfuck/blob/master/jsfuck.js
         | 
         | With this I was able to get the letter 'a' by starting with
         | their initial definition `(false+"")[1]`, then continually
         | substituting
         | 
         | (false+'')[1]
         | 
         | (![]+'')[1]
         | 
         | (![]+([]+[]))[1]
         | 
         | (![]+([]+[]))[+!(+[])]
         | 
         | All of the above lines when evaluated result in 'a'.
        
           | hn_throwaway_99 wrote:
           | Yep, in addition the other part that helped me understand was
           | how it encodes eval for actually executing code. Details are
           | on this line, https://github.com/aemkei/jsfuck/blob/1f02651e9
           | 8da1c13aef76d... , and details of that are:
           | 
           | 1. [] => An array object
           | 
           | 2. []["flat"] => The built in flat function on the Array
           | object
           | 
           | 3. []["flat"]["constructor"] => The constructor of any JS
           | function is the Function constructor, which can take
           | JavaScript, as a string, as its sole parameter. Thus, to
           | create a function that executes any CODE_AS_STRING:
           | 
           | 4. []["flat"]["constructor"](CODE_AS_STRING) => gives you the
           | Function object, and finally:
           | 
           | 5. []["flat"]["constructor"](CODE_AS_STRING)() => executes it
           | 
           | Thus, all that's left is to encode the strings "flat",
           | "constructor" and CODE_AS_STRING using the patterns described
           | early in that file.
        
         | [deleted]
        
         | tacticalmook wrote:
         | brainfuck isn't an obfuscator, but a language with a very small
         | and simple instruction set. Technically it falls somewhere
         | between c and assembly, since it doesn't have a 1:1
         | relationship with machine code, but in practice it is less
         | powerful than assembly because you have to work within the
         | confines of its restrictive conventions to recreate something
         | as simple as y = x
         | 
         | There are some tasks which lend themselves to the way the
         | language is constructed, and can be done with few instructions.
         | 
         | Reversing a string, for example, is just ,[[<]<+>>[>],]<[.<]
         | which is quite short compared to most "practical" programs in
         | this language.
         | 
         | And a destructive y = y + x is just [->+<] (destructive because
         | this also sets x to zero)
        
         | colejohnson66 wrote:
         | This isn't related to BF (despite looking like it). At the
         | bottom of the page, it explains how the conversions work.
         | Basically, it takes advantage of JavaScript's loose typing and
         | implicit conversions.
        
         | mb7733 wrote:
         | It's because it _is_ working javascript. It's just obfuscated,
         | taking advantage of the quirks of javascript's implicit type
         | casting to represent expressions in odd ways. Look at the
         | "basics" section of the page to get an idea of how it works on
         | a small scale.
         | 
         | Brainfuck is an unrelated, separate programming language.
        
       | abacadaba wrote:
       | New interview question: What will be the result of running the
       | following code?
       | 
       | [][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+
       | (!![]+[])[+[ ]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][(
       | ![]+[])[+[]]+([![]]+[][[] ])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!!
       | []+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+ (!![]+[])[+!+[]]]+[])[!+[]
       | +!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+ !+[]+[+[]]]+(
       | ![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![ 
       | ]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]
       | +!+[]]+(!![] +[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]
       | +[])[+[]]+([![]]+[][[]])[ +!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+
       | [])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!! []+[])[+!+[]]]+[])[!+[]+!+
       | []+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![ ]]+[][[]])[+!
       | +[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[ 
       | ]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[]
       | )[+!+[]]+(![ ]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])
       | [+!+[]]+(!![]+[])[+[]]+(! []+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[
       | ]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[]) [+[]]+(!![]+[])[!+[]+!+[]+
       | !+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+( !![]+[][(![]+
       | [])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[ 
       | ])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+
       | []]])()
        
         | Aeolun wrote:
         | I think someone once asked me the simplified variant of that
         | question.
         | 
         | What is the result of:                 []+[]
         | 
         | And I didn't know the answer to _that_ (I mean, who does that
         | kind of fuckery in Javascript, you can't sum arrays). I would
         | have no chance with these Google level questions.
        
           | 8note wrote:
           | "let's try running it and find out"
        
             | Aeolun wrote:
             | Haha, yeah, that was about my answer. "No idea, but now
             | that you ask me I'm interested."
        
           | forty wrote:
           | It's a stupid question, unless they also give you the
           | ecmascript spec and let you figure it out ;)
        
           | tigerlily wrote:
           | I think I would just delete it.
        
           | shrimpx wrote:
           | That's an idiotic interview question. I've experienced this
           | at young companies where both the company and its engineers
           | are too immature to understand basic etiquette in the
           | industry. Btw I doubt Google would ask a stupid "gotcha"
           | question like that. They tend to ask hard algorithmic
           | questions.
        
             | seanp2k2 wrote:
             | FWIW I've had Google recruiters ask me stuff where they
             | don't understand the answer and the questions are things
             | like "what is the protocol number for ICMP" and "what port
             | does NTP use". If one doesn't work with these things very
             | often, they're very forgettable as they're so easy to
             | google and find the correct answer to in seconds, and
             | therefore not worth memorizing. No idea if they're still
             | doing this, but it was like a crappy version of Hacker
             | Jeopardy (#DFIU!). After about 6 months of back and forth
             | with the recruiter and a few interviewers missing
             | interviews, I just gave up and told them I was no longer
             | interested.
        
               | Aeolun wrote:
               | Is a pretty silly question too, since NTP uses whatever
               | port you set it to.
        
               | dboreham wrote:
               | Never talk to recruiters.
        
               | mr_toad wrote:
               | > "what port does NTP use".
               | 
               | I'd just Google it.
        
               | 10x-dev wrote:
               | I went through the swe generalist interview pipeline 3
               | times at Google, so that's about 15 interviews. All the
               | questions have been standard , except this one dumb
               | question, which was along the lines of "explain how
               | multithreading works". I suppose he wanted me to follow
               | up with some questions to narrow down the topic, but I
               | was stressed out enough that I just started with the
               | basics, like cores, processes, OS threads, and shared
               | memory, trying to explain it in simple terms. He
               | interrupted me about 5 minutes in and moved on.
               | 
               | Having interviewed people myself, I think that's an
               | overly broad question to ask in an interview and if the
               | candidate starts answering it as asked, then you're not
               | going to get a lot of signal from it.
               | 
               | Otherwise I thought the problems asked weren't that
               | difficult, one was even directly taken from Cracking the
               | Coding Interview - if only I had read that chapter ahead
               | of the interview...
        
             | inoffensivename wrote:
             | > I doubt Google would ask a stupid "gotcha" question like
             | that.
             | 
             | You're kidding, right?
        
               | shrimpx wrote:
               | Do Google interviewers ask whatever they want, without
               | any standard? Or is the standard idiotic, allowing for or
               | encouraging questions like that?
        
             | forgetfulness wrote:
             | Only in Amazon interviews I've had actual trivia questions,
             | like having been asked questions that'd require you to know
             | all POSIX signals by memory (that could be fair if you
             | squint a bit) or, more absurdly, solve a problem tailored
             | for a particular flag of the find utility (which I realized
             | when I looked at the manual for the thing again), as any
             | other solution was too complicated to be satisfactory.
        
             | bgro wrote:
             | Heh, what's this? You can't answer this question off the
             | top of your head after I spent 2 hours purposefully
             | researching obscure edge cases to craft it? I guess you're
             | not a real engineer. Did you even pass the 101 courses? No,
             | no, no... You're no fit for us here. You see, some of us
             | have to actually work for a living. Try pulling yourself up
             | by the bootstraps next time, kiddo!
        
           | thamer wrote:
           | In case anyone is wondering, the answer is '' (empty string).
        
             | najmlion wrote:
             | How can adding two empty arrays give you an empty string?
        
               | abdusco wrote:
               | That's Javascript for you.
               | 
               | Summing arrays calls `.toString()` on them, and two empty
               | string gives you a new empty string.
               | [].toString() === ''         [] + []              === ''
               | + ''              === ''
               | 
               | https://github.com/denysdovhan/wtfjs#adding-arrays
        
               | superice wrote:
               | The + operator doesn't work on arrays, but tries to cast
               | the sides of it to a string. Arrays implement the
               | toString function, which shows the toString of the
               | individual values comma separated. An empty array returns
               | an empty string. Which means that this is equivalent to
               | empty string + empty string.
               | 
               | [ 'foo', 'bar ] + [ 'baz' ] would return 'foo,barbaz'
        
           | idolaspecus wrote:
           | This is in my opinion actually a decent interview question.
           | If you know JS in detail, if you know how the "+" operator
           | works, it's a super easy question. If you don't know JS in
           | detail, if you don't know how the "+" operator works, it's
           | pretty tough. If you want an engineer who knows JS in detail,
           | asking this question can be valuable.
        
             | Aeolun wrote:
             | That _may_ be relevant if you are working on a javascript
             | engine, not if you build webapplications.
        
             | colordrops wrote:
             | "+" isn't some singular operator. They are different
             | operators for different types using the same character.
             | You'd have to memorize a table of all JS types and what "+"
             | does for each, which is silly considering that the only
             | place it should really be used in modern JS is arithmetic
             | and the occasional string concatenation.
        
               | dorgo wrote:
               | afaik these two places ( arithmetic and string
               | concatenation ) are the only ones where + operation is
               | defined. JS picks one of these two operations and casts
               | the operands accordingly.
               | 
               | Edit: Wait, there is also the unary + which takes only
               | one argument, but it also could be considered arithmetic.
        
             | afiori wrote:
             | it would be more relevant to ask about the valueOf method
             | that can mess up all the various conversions.
        
           | IncRnd wrote:
           | The right type of answer for that is to laugh and say, "you
           | should ask the fool who wrote that code instead of asking
           | me."
        
             | moron4hire wrote:
             | This kind of thing does happen in the wild, through no
             | fault of anyone in arms' reach, in particular when service
             | APIs change in subtle and unexpected ways.
             | 
             | You might have a service that yesterday returned a JSON
             | payload:                   { tasks: 5, ... }
             | 
             | but today returns:                   { tasks: [{...}, ...],
             | ...}
             | 
             | If you had an array of these objects and were trying to sum
             | the count of tasks, now your code returns weird results.
             | Knowing how the JS engine's type coercion works is then
             | invaluable for figuring out the problem quickly.
             | 
             | Yes, it's shitty code, and a change of API like that is
             | shitty. But we don't always get to choose what code we're
             | interfacing with, particularly when it comes to web
             | services.
        
               | seanhunter wrote:
               | Sure, but in the wild, you would actually run the thing
               | in the repl to see what it does. So either you know the
               | answer or you don't and it doesn't affect whether or not
               | you can do the job well. In my opinion binary knowledge-
               | based questions are seldom useful unless you specifically
               | are checking for that exact knowledge. You can have
               | someone who is totally terrible in general but just knows
               | that one thing or the answer to that specific trick
               | question and you can have people who would be fantastic
               | for the role but either don't know the answer or can't
               | think of it because of a mental block in the moment. ie
               | the false negative and false positive rate are too high
               | and your question is just a random classifier.
               | 
               | Questions that allow a person to show their skill and
               | their thought process are much more revealing. They're
               | much harder to fake and bluff your way through for poor
               | candidates and they allow good candidates to show their
               | skill. They require a bit more effort from the
               | interviewer though because there isn't just one right
               | answer and you have to sacrifice the idea that you get an
               | ego boost by dunking on some poor candidate with your
               | trick question.
               | 
               | An example of a question I used to ask when interviewing
               | candidates who said they were good at unix: "Say I have a
               | directory full of files called a, b, c, etc and I want to
               | rename them all to a.bar, b.bar, c.bar etc how do I do
               | that"? Then I would follow up with "Ok now I have a
               | directory full of files called a.bar, b.bar, c.bar etc
               | and I want to rename them back to a, b, c, how do I do
               | that?".
               | 
               | Now if you know unix you know there are a bunch of ways
               | to do this, there are a bunch of traps you can fall into,
               | what if there are too many files for shell expansion,
               | what if the file names contain spaces etc. It's not hard
               | for someone skillful to come up with a few ways that deal
               | with these issues and if they can talk through how they
               | did it and why then any of them are fine.
               | 
               | Edit to add: There is a kernel of value here though,
               | which is say you were debugging a thing where the result
               | was an empty string and you thought "wow, that makes no
               | sense", maybe you get to understanding what went wrong
               | when you see that two arrays are getting type coerced or
               | something.
        
               | moron4hire wrote:
               | My reply was less about whether or not it's a good
               | interview question and more about the comments people are
               | making in this thread that the question is completely
               | invalid because only a "fool" would write code like that.
               | 
               | In practice, unless you have some extremely pedantic, end
               | to end testing, your first hint that something is going
               | wrong is probably going to be malformed output.
               | TypeScript won't catch this error because it doesn't do
               | runtime checking, it trusts that type annotations are
               | correct. It's very possible for code like this to pass
               | through without causing any exceptions to throw. Indeed,
               | JavaScript was originally designed to "keep on trucking"
               | in this way, and that's why we have this degree of type
               | coercion. So you're going to be working backwards from a
               | result rather than forward from a source. If you already
               | know how your code works and you see a weird result like
               | that, knowing the type coercion gotchas can help you work
               | backwards to understanding where the change occurred.
               | 
               | But in the former issue, I don't think the question on
               | its own is bad for job interviews. How the question is
               | used is what determines if it's good or bad. For example,
               | it is a little unreasonable to expect people to know
               | every single, little gotcha in JavaScript and the exact
               | way in which they misbehave. But I do think it's
               | reasonable to expect people to know that there are
               | gotchas and that this is a common one. I'd accept as a
               | valid answer, "I don't know the exact results, but I do
               | know that this doesn't concatenate arrays and instead
               | does something unexpected".
        
               | IncRnd wrote:
               | > My reply was less about whether or not it's a good
               | interview question and more about the comments people are
               | making in this thread that the question is completely
               | invalid because only a "fool" would write code like that.
               | 
               | If you ask about how to uppercase a string, certain
               | constructs like []+[], or whether camelCase or PascalCase
               | is superior you will get the people who know the answers
               | to those questions.
        
           | dylan604 wrote:
           | looks like you need to watch the WAT talk
           | 
           | https://www.destroyallsoftware.com/talks/wat
        
             | danwills wrote:
             | Thanks for the reminder, love to re-watch this every now
             | and again! So funny!
             | 
             | Does ayone know of any similar-calibre sequels or similar
             | vids?
        
             | dorgo wrote:
             | [] + {} is not an object but a string.
        
               | [deleted]
        
           | spurgu wrote:
           | That's interesting. +[] is quicker to type than toString().
           | Wonder if there are any caveats. :D
        
         | andersco wrote:
         | The answer, obviously, is 42.
        
           | [deleted]
        
         | [deleted]
        
         | vincent-manis wrote:
         | 42
        
         | [deleted]
        
         | nostoc wrote:
         | JS-fuck is trivial to unpack if you have access to a javascript
         | repl. Your code does a simple :                   alert(1);
         | 
         | here's how you do it :
         | 
         | https://i.imgur.com/fBDLD8z.png
        
         | eyelidlessness wrote:
         | "This is the most interesting interview question I've ever
         | walked out on"
        
         | godmode2019 wrote:
         | https://m.youtube.com/watch?v=dQw4w9WgXcQ
        
       | MihaiSandor wrote:
       | It"s very interesting when you play code golf . Check this out
       | (https://codegolf.stackexchange.com/a/17980). You have 100%
       | chance to lose
        
       | everyone wrote:
       | https://youtu.be/3se2-thqf-A
        
       ___________________________________________________________________
       (page generated 2021-09-26 23:02 UTC)