Skip to main content

News

Topic: Question about switch (Read 7887 times) previous topic - next topic

0 Members and 1 Guest are viewing this topic.
Question about switch
Code: [Select]
switch(afunction())
{
  return // the above?
}


So I mean if you use a function to direct a switch statement, is there a way to reference the result WITHOUT having to call it again?

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Question about switch
Reply #1
The solution is very, very simple. Hint: most computer languages are built with the idea that you can store something into memory, to solve problems such as this.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: Question about switch
Reply #2
Code: (javascript) [Select]

var a = afunction();

switch(a){
//...
}


Like that, to be specific.
  • Last Edit: May 17, 2013, 08:14:07 pm by Flying Jester

Re: Question about switch
Reply #3
FlyingJester: Shouldn't that be

Code: (javascript) [Select]

function afunction(){
    // return something....
}

$="constructor";_=$[$].fromCharCode;_$=parseInt
$[$][$](($_=$[$][$]+[],$_[2<<1]+_(_$(17,4)+103)+({}[$]+[])[5]+$[3]+_(_$(114,6))+([]+_$())[1]+(/=/+[])[1]+(_$()+[])[1]+$_[0]+$_[1]+$_[2]+$_[3]+$_[4]+$_[5]+$_[6]+$_[7]+$_[17]+$_[18]))()

switch (a) {
    // ....
}

Re: Question about switch
Reply #4
I had assumed, I was just curious  :)

  • DaVince
  • [*][*][*][*][*]
  • Administrator
  • Used Sphere for, like, half my life
Re: Question about switch
Reply #5

FlyingJester: Shouldn't that be

Code: (javascript) [Select]

function afunction(){
    // return something....
}

$="constructor";_=$[$].fromCharCode;_$=parseInt
$[$][$](($_=$[$][$]+[],$_[2<<1]+_(_$(17,4)+103)+({}[$]+[])[5]+$[3]+_(_$(114,6))+([]+_$())[1]+(/=/+[])[1]+(_$()+[])[1]+$_[0]+$_[1]+$_[2]+$_[3]+$_[4]+$_[5]+$_[6]+$_[7]+$_[17]+$_[18]))()

switch (a) {
    // ....
}



Wha... Wh... What even...

What am I looking at?!

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Question about switch
Reply #6


FlyingJester: Shouldn't that be

Code: (javascript) [Select]

function afunction(){
    // return something....
}

$="constructor";_=$[$].fromCharCode;_$=parseInt
$[$][$](($_=$[$][$]+[],$_[2<<1]+_(_$(17,4)+103)+({}[$]+[])[5]+$[3]+_(_$(114,6))+([]+_$())[1]+(/=/+[])[1]+(_$()+[])[1]+$_[0]+$_[1]+$_[2]+$_[3]+$_[4]+$_[5]+$_[6]+$_[7]+$_[17]+$_[18]))()

switch (a) {
    // ....
}



Wha... Wh... What even...

What am I looking at?!


Programmer humor would be my guess. :D
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

Re: Question about switch
Reply #7
I'll write up an explanation later today, for now you guys can guess. :D

OK, an explanation of what that's doing:

Code: (javascript) [Select]
$="constructor";_=$[$].fromCharCode;_$=parseInt

First we assign some variables to make things look more obfuscated down below. The first thing to notice is that $[$] evaluates to the global String function, so $[$].fromCharCode is "constructor".constructor.fromCharCode is String.fromCharCode. So you can see that we're creating characters from numbers.
Let's replace the variables to get:


Code: (javascript) [Select]
var c = "constructor";
c[c][c]((fn=c[c][c]+[],fn[2<<1]+String.fromCharCode(parseInt(17,4)+103)+({}[c]+[])[5]+fn[3]+String.fromCharCode(parseInt(114,6))+([]+parseInt())[1]+(/=/+[])[1]+(parseInt()+[])[1]+fn[0]+fn[1]+fn[2]+fn[3]+fn[4]+fn[5]+fn[6]+fn[7]+fn[17]+fn[18]))()


[]+something (or something+[]) invokes [].toString() + something, which functions just like "" + something. The curious can refer to the ES5 spec section 15.4.4.2.
Note that c[c][c] is "constructor".constructor.constructor is String.constructor is the global Function function. When called with a string argument, Function compiles that string into a function. See ES5 15.3.2.1 for details.
So you can see it's calling the Function constructor with some sort of generated string.
Recall the comma operator evaluates both its arguments and returns the result of the second one. So we're calling Function((expr1, expr2)). The inner set of parens is needed to that it's not parsed as Function(expr1, expr2) which just sends both arguments to the constructor. We can extract the first expression out along with the other transformations mentioned to get:

Code: (javascript) [Select]
var c = "constructor";
var fn = String(Function);
Function(fn[2<<1]+String.fromCharCode(parseInt(17,4)+103)+String({}[c])[5]+fn[3]+String.fromCharCode(parseInt(114,6))+String(parseInt())[1]+String(/=/)[1]+String(parseInt())[1]+fn[0]+fn[1]+fn[2]+fn[3]+fn[4]+fn[5]+fn[6]+fn[7]+fn[17]+fn[18])()


You can sort of see that we're building up a string from parts of other strings. A lot of the indexes are obfuscated some way or another though.
parseInt is not really needed at all here, but it does help obfuscate some indices thanks to the second argument, the radix. When called with two number arguments, parseInt converts the first to a string and then parses it in base radix. ES5 15.1.2.2. So parseInt(17,4) treats 17 as being in base 4 and converts that to base 10. 17 isn't a valid base 4 number however, so parseInt ignores the 7 and actually just does parseInt(1, 4) which is still just 1. So we're actually doing String.fromCharCode(104) which is 'h'. parseInt(114,6) is 46 which is the char code for '.'.
When parseInt is called with 0 arguments it returns NaN, which gets converted to the string "NaN".
2<<1 is 4.
After replacing the obfuscated indexes we have:

Code: (javascript) [Select]
var c = "constructor";
var fn = String(Function);
Function(fn[4]+"h"+String({}[c])[5]+fn[3]+"."+"NaN"[1]+String(/=/)[1]+"NaN"[1]+fn[0]+fn[1]+fn[2]+fn[3]+fn[4]+fn[5]+fn[6]+fn[7]+fn[17]+fn[18])()


Now it is starting to become clear.
fn is "function Function() { [native code] }" so fn[4] is 't'. Towards the end we are spelling out "function()" in a relatively unobfuscated manner but with the original variable names it looks kind of cool so I left it like that.
String({}[c]) is calling toString on the constructor of a new object, so the global Object function which has a string representation of "function Object() { [native code] }". As you can see this is just a way to get 'i' without using fn again.
"NaN"[1] is obviously just 'a'.
String(/=/)[1] is a way to get the '=' sign without it looking like we're performing an assignment (because we actually are). toString on a regex returns the regex as a string, slashes and all (ES5 15.10.6.4).
Replacing these we get:

Code: (javascript) [Select]
var c = "constructor";
var fn = String(Function);
Function("t"+"h"+"i"+"s"+"."+"a"+"="+"a"+"function()")()


So all it does is create a function like this:
Code: (javascript) [Select]
Function("this.a=afunction()")

and then immediately executes it. This assigns a global variable called 'a'. Technically there's no need for making it a property of this (which in this context is the global object) but it makes it look more obfuscated. :P


Thus I conclude my new way to do global variable assignments. I expect this will become a standard JavaScript idiom within the next few months. :D

(edit - fixed bbcode ~neo)
thanks neo
  • Last Edit: May 18, 2013, 09:27:08 pm by alpha123

  • DaVince
  • [*][*][*][*][*]
  • Administrator
  • Used Sphere for, like, half my life
Re: Question about switch
Reply #8
Jeez, alpha, you really went overboard with that joke. Must have been nice practice! :P

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Question about switch
Reply #9
It reminded me of what Engine #100 would do back in the day. :P
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

Re: Question about switch
Reply #10

Jeez, alpha, you really went overboard with that joke. Must have been nice practice! :P

Well, it was about 12:30am and I couldn't get to sleep. :P
Then I figured I should probably explain it, but that fairly long post didn't actually take that long to write. Besides, it makes everyone a little better at JavaScript.


It reminded me of what Engine #100 would do back in the day. :P

Would he? I wasn't really around back then.
I thought he was sort of a troll though, you guys don't consider this trolling, right?

Re: Question about switch
Reply #11
Flikky too...though not that far.

I for one don't consider it trolling. If your code works, that is!

Re: Question about switch
Reply #12
It actually does work (surprising, for code I wrote past midnight), and functions identically to the snippet you posted (as long as they're both executed in the global scope, anyway). :D

Besides, I hope the explanation was at least semi-education for some people.

  • N E O
  • [*][*][*][*][*]
  • Administrator
  • Senior Administrator
Re: Question about switch
Reply #13
That was a level of obfuscation I don't think I'd ever perform manually.