[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)