149

this question is difficult to summarize in a question title

UPDATE I created a JSFiddle that builds an obfuscated string out of your input based on the letters extracted from this question: You can access it here, or would a gist be easier?

I recently came across a fun bit of obfuscated JavaScript in this profile that looks like this:

javascript:[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-
[])[1<<1]+[/~/+{}][+!1][-~1<<1]+([]+/-/[(!!1+[])[1>>1]+(!!1
+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+([,][
~1]+[])[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+(/1/+
1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</[1]+[])[1/1.1&1]

Sorry to ruin the surprise but when this is evaluated it returns this:

"I love you" in Chrome
"I lone you" In Firefox
"I lo[e you" in IE10

The way this works when broken out, is to generate a series of messages and to pull letters out of them like so (using the "I" as an example):

[]+1/!1
returns
"Infinity"
then
[[]+1/!1]
creates this array:
["Infinity"]
then
[[]+1/!1][1^1]
Takes the first (1^1 == 0) element of that array
"Infinity"
finally
[[]+1/!1][1^1][1>>1]
Takes the first (1>>1 == 0) char of that string
"I"

Other strings that are generated include:

({}+[])       -> "[object Object]" (where the space comes from)
([]+!!-[])    -> "false" (used for it's "l")
[/~/+{}][+!1] -> "/~/[object Object]" (this is used for an "o")
(/<</[1]+[])  -> "undefined"

I was interested in finding a replacement for the "n" and "[" and came up with this:

String.fromCharCode(('1'.charCodeAt(0)<<1)+(10<<1))

Which I feel in in the spirit of using 1's and 0's, but violates one of the more elegant aspects of the original code which is the appearance of having nothing to do with strings at all. Does anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?

Here is some extra information that was found after many talented JavaScript programers took a deeper look at this

Firefox returns "I lone you" Because of this line:

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+

[1^11<<1] trims a specific character from this:

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])

Which evaluates to this:

"function test() {
    [native code]
}"

Which looks like we might have our "V"!!!

Chrome returns "I love you", because the same code returns this:

"function test() { [native code] }"

Before the question is closed for questionable connection with "a real programming issue", I thought I'd add a summarized solution that builds on @Supr's, @Cory's and @alpha123's, behold:

alert([[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+(
[]+!!-[])[1<<1]+[/~/+{}][+!1][-~1<<1]+[([]+/-/[(
!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(
!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],([]+/-/[(!!1+[
])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[
])[1^1]])[1^11<<1],([]+/-/[(!!1+[])[1>>1]+(!!1+[
])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11
+1+1)<<1]][((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<
1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1
)+1<<1]==({}+[])[1^1])*1)+((([]+/-/[(!!1+[])[1>>
1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1
]])[(1^11<<1)-1]==({}+[])[1^1])<<1)]+([,][~1]+[]
)[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+
(/1/+1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</
[1]+[])[1/1.1&1])

Given the complexity of the code and the message it produces it's almost like the JavaScript engine is telling how special you make it feel :)

Community
  • 1
  • 1
Jason Sperske
  • 29,816
  • 8
  • 73
  • 124
  • Can you get `"void"`? – John Dvorak Apr 12 '13 at 18:20
  • Related/possible duplicates: http://stackoverflow.com/questions/4170978/explain-why-this-works?lq=1, http://stackoverflow.com/questions/7202157/can-you-explain-why-10 – bfavaretto Apr 12 '13 at 18:20
  • 1
    The original code returns "I lone you" I'm trying to make it say "I love you" – Jason Sperske Apr 12 '13 at 18:21
  • I lone you, cause is make for the character by the different results.. – ncubica Apr 12 '13 at 18:21
  • 9
    It does say "love" in the Chrome console. http://i.imgur.com/rVyKMoP.png – bfavaretto Apr 12 '13 at 18:21
  • Oh Interesting... I had been testing this in Firebug, I didn't consider it being a a browser difference – Jason Sperske Apr 12 '13 at 18:22
  • 1
    Is not Duplicate, he is trying to get the "V" value no understand why is this working. – ncubica Apr 12 '13 at 18:23
  • 1
    so, let's find out how it obtains V in chrome? – John Dvorak Apr 12 '13 at 18:24
  • @nahum Yeah, realized it a little too late. – bfavaretto Apr 12 '13 at 18:26
  • This is the line that returns 'n' in Firefox: `([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]+` – Jason Sperske Apr 12 '13 at 18:28
  • There's `Object.prototype.valueOf()` and also `eval()` and the related `EvalError()`. But I'm not sure off the top of my head how to extract the `v` from any of those – Nathan Friedly Apr 12 '13 at 18:28
  • Essentially, if needed, something as simple as `0*{}` would return `NaN` so you could a capital N. – h2ooooooo Apr 12 '13 at 18:31
  • @h2ooooooo They want a lowercase "V" – Ian Apr 12 '13 at 18:32
  • 1
    The difference between chrome and firefox is basically that `([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])` returns text with formatting spaces, but chrome returns the same text with different, inline formatting. – G-Nugget Apr 12 '13 at 18:32
  • @Ian I know, I'm simply adding the fact that if someone else is trying to make something similar. – h2ooooooo Apr 12 '13 at 18:32
  • 2
    What if you strip non letters from the `function test() { [native code] }`, then you could normalize it and extract the letter you want – Jason Sperske Apr 12 '13 at 18:36
  • `([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]` gives me `v` in chrome from `"function test() { [native code] }"` – TheBrain Apr 12 '13 at 18:37
  • 4
    Basing code on a non-standards-defined string output in order to print a message using obfuscated code... I'm calling this one ***way*** too localized. –  Apr 12 '13 at 18:38
  • 1
    @TheBrain They already know how to get it in Chrome..it's Firefox that has the "issue" – Ian Apr 12 '13 at 18:38
  • @JasonSperske I agree, but how do you expect to do that without using `replace`? – Ian Apr 12 '13 at 18:39
  • 2
    @Ian, true. If the people in my life that I love really cared about me they would use Chrome :) – Jason Sperske Apr 12 '13 at 18:40
  • Are you trying to avoid function calls entirely? – svidgen Apr 12 '13 at 18:40
  • @JasonSperske Haha good to know. I'm just saying, the OP wants to keep this completely obfuscated, so any recognizable text isn't good – Ian Apr 12 '13 at 18:41
  • @svidgen I think they're just trying to keep it completely obfuscated. Function calls are sensible and recognizable, so I guess the answer to your question is "yes"...unless you can do it in a sneaky way (like the rest of the code) and don't have to type the function name – Ian Apr 12 '13 at 18:42
  • ...but if you want a lowercase `"v"`, why not just stringify `eval()`? –  Apr 12 '13 at 18:42
  • @amnotiam Because you can clearly see that the word "eval" is being used in the obfuscated code then. The point is that there's no way to identify what's even being remotely done. If someone saw "eval" in that string, they could infer that's how the "v" is gotten. – Ian Apr 12 '13 at 18:44
  • This might be a dumb question, but how does the part in question generate the function's name as "test"? – Ian Apr 12 '13 at 18:49
  • @Ian it pulls the letters from `true` and `false` – G-Nugget Apr 12 '13 at 18:51
  • For those who are wondering: `typeof` doesn't return anything useful anywhere, and it's not even available – John Dvorak Apr 12 '13 at 18:52
  • If only I could replace every `f` with `f.bind` or `(function(){return f})` , the rest would be easy – John Dvorak Apr 12 '13 at 19:07
  • ... but `valueOf` is not enumerable – John Dvorak Apr 12 '13 at 19:07
  • +1 for showing me how to mine points with an awesome question. – Erik Reppen Apr 12 '13 at 23:10
  • 1
    Also for a way to send my tech-illiterate wife a love note in JavaScript that will annoy the crap out of her once she figures out the chrome console directions. – Erik Reppen Apr 12 '13 at 23:17
  • 1
    Well, sorry for the *non Chrome* mistake. While creating that I had only Chrome installed, so as my wife `:)` – VisioN Apr 15 '13 at 22:19
  • @JasonSperske BTW, have you noticed that every question revision the digit in the last line of my code is increasing? When I posted my answer it was `2`, now it is `4`. And basically you also have `8` in one of the last lines of your version. Looks like a magic bug in markdown. – VisioN Apr 16 '13 at 23:01
  • I hadn't noticed that. Looks like all the square brackets in the code are causing problems with Markdown's "add hyper link" button. When you add a link it tries to adjust the number of each of the links to keep the list in order. – Jason Sperske Apr 16 '13 at 23:05
  • @JasonSperske I have adapted your idea about creating an obfuscation tool, and coded a bit another version. Please check my updated answer. You can test and amend it if you enjoy `;)` – VisioN Apr 17 '13 at 18:03
  • Should this be moved to [codegolf.se] under the tag "popularity-contest"? – Claudia Mar 01 '14 at 18:44
  • 4
    The best part about this is the warning my text editor gives: "Confusing use of '!'" – Jake Johnson Mar 04 '14 at 02:37

7 Answers7

84

First of all, I would like to thank Jason and all the contributors for playing with that funny snippet. I have written that piece of code just for fun in order to send it to my wife on February 14 :) Having only Chrome installed on the laptop I had no options to check how it works in Firefox and IE. Moreover, I haven't really expected that toString() representation of build-in methods might look differently in other browsers.

Now, moving to the real problem, let's precisely have a look at the code. Yes, "v" was the real "problem" here. I found no other ways of getting this letter except parsing [native code] string, which can be taken from any built-in method. Since I limited myself with having no strings and no numbers except 1 used, I needed to exploit some method that has only available characters in its name.

Available characters can be obtained from existing keywords and string representations, i.e. from the start we had NaN, null, undefined, Infinity, true, false, and "[object Object]". Some of them can be easily converted to strings, e.g. 1/!1+[] gives "Infinity".

I have analyzed different build-in methods for arrays [], objects {}, regular expressions /(?:)/, numbers 1.1, strings "1", and discovered one beautiful method of RegExp object called test(). Its name can be assembled from all available characters, e.g. "t" and "e" from true, and "s" from false. I have created a string "test" and addressed this method using square brackets notation for regex literal /-/, correctly identified in this line:

/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]]

As was already discussed, this piece of code is evaluated in Chrome as:

function test() { [native code] }

in Firefox as:

function test() {
    [native code]
}

and in IE as:

 function test() {     [native code] }  

(in the latter pay special attention to the space before function keyword)

So, as you clearly see, my code was getting the 24th character from the presented string, which in Chrome was "v" (as was planned), but unfortunately in Firefox and IE -- "n" and "[" respectively.

In order to make the same output in all the browsers, I have used different approach than illustrated in the other answers. Now the modified version looks like that:

javascript:[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-
[])[1<<1]+[/~/+{}][+!1][-~1<<1]+/\[[^1]+\]/[([]+![])[1<<1<<
1]+(/|/[(1+{})[1+11>>>1]+[[]+{}][+!1][1]+([]+1/[])[1<<1>>1]
+([1<1]+[])[1+11>>>1+1]+[[!!1]+1][+[]][1-1]+([]+!!/!/)[1|1]
+(/1/[1]+[])[!1%1]+(-{}+{})[-1+1e1-1]+(1+[!!1])[1]+([]+1+{}
)[1<<1]+[!!/!!/+[]][+[]][1&1]]+/=/)[1e1+(1<<1|1)+(([]+/-/[(
!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1
]])[1^1]==+!1)]+(!![]+{})[1|1<<1]+[1+{}+1][!1+!1][(11>>1)+1
]](([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+
(!!1+[])[1^1]]))[1&.1][11>>>1]+([,][~1]+[])[1-~1]+[[]+{}][!
1.1%1][11111.1%11.1*111e11|!1]+(/1/+1/[1<1][1%1])[1^11]+[[]
,[]+{}][1<<1>>>1][1||1]+(/[<+>]/[1&1|1]+[1.1])[1/11.1&1.11]

However, in order to intrigue the readers I won't provide a solution for that. I honestly believe that you will easily understand how it works... and some can even surprise their beloved in cross-browser way ;)

P.S. Yet Another Obfuscator

Inspired by Jason's idea to create a universal obfuscating tool, I have written one more. You can find it at JSBin: http://jsbin.com/amecoq/2. It can obfuscate any text that contains numbers [0-9], small latin letters [a-z], and spaces. The string length is limited mostly with your RAM (at least the body of my answer was successfully obfuscated). The output is supported by Chrome, Firefox, and IE.

Hint: the tool uses different obfuscation approach than was presented above.

Community
  • 1
  • 1
VisioN
  • 143,310
  • 32
  • 282
  • 281
26

Why isn't the native code bit from the question being used? This one gives a 'v' in both Chrome and Firefox:

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]>([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]?([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]:([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]

Edit to support IE and do it without the ternary operator: This one works in Chrome, IE, and FF. Builds an array and uses == to determine browser.

[([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1],([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]][((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1)+1<<1]==({}+[])[1^1])*1)+((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)-1]==({}+[])[1^1])<<1)]

Readable:

[
    //ie
    ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)],
    //ch
    ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1],
    //ff
    ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^(11+1+1)<<1]
]
[
    //ch?
    ((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1<<1<<1<<1)+1<<1]==({}+[])[1^1])*1)+
    //ff?
    ((([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)-1]==({}+[])[1^1])<<1)
]
Supr
  • 18,572
  • 3
  • 31
  • 36
  • That is interesting. Originally it has been dismissed that the placement of the words "native code" was unpredictable between Firefox and Chrome. This solve that but doesn't work in IE10 (where it returns "i"). Still I wonder if this option might offer some fresh ideas – Jason Sperske Apr 12 '13 at 22:38
  • The idea is to just select both `n` and `v` and just pick whichever is largest: `str[23]>str[27]?str[23]:str[27]`. In other words, the tertiary operator is the trick. Could be extended to support IE as well: `([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1+(1^(11+1+1)<<1)]` – Supr Apr 12 '13 at 22:52
  • All without a single letter, quote mark or obvious function name and in all three browsers. Amazing. – Jason Sperske Apr 12 '13 at 23:48
  • 1
    Your answer was first (ahead of the creator of the original code), but I felt his answer could most logically be considered the correct one. Still great job (and a well deserved 13 up votes) – Jason Sperske Apr 16 '13 at 19:44
  • 1
    Minor nitpick: a tertiary operator is the third most important operator, after the primary and secondary. An operator which takes three operands is ternary. – Eric Lippert Apr 24 '13 at 00:42
  • 1
    @EricLippert, gah, I even googled it to make sure I was using the right term, yet I still ended up with the wrong one! Thanks, corrected. – Supr Apr 24 '13 at 07:36
8

This is about as close as I could get, unfortunately it violates the convention of the original obfuscation by making a call to unescape():

unescape((/%/+[])[1]+(/1/[1]+[])[1%1]+(+!1)+(+!1)+(1e1+(11*(1-~1)<<1)))

Teardown:

(/%/+[])[1]          => "%"
(/1/[1]+[])[1%1]     => "u"
(+!1)                => "0"
(+!1)                => "0"
(1e1+(11*(1-~1)<<1)) => "76"
===========================
unescape("%u0076")   => "v"

Other ideas:

  1. Somehow get to unescape("\x76")
  2. Somehow convert 118 without calling String.fromCharCode()
  3. Get the text from an exception with the word "Invalid" in it

Updates:

I started playing code golf and have been making it shorter, replacing parts with more 1s, etc.

Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
4

Here's the part that generates the n/v:

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[1^11<<1]

In Firefox, ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]]) evaluates to

"function test() {
    [native code]
}"

while in Chrome it is

"function test() { [native code] }"

1^11<<1 equals 23. So due to Firefox's extra whitespace, this isn't quite enough to get to the 'v', and is instead 'n'.

And this is why you shouldn't rely on Function#toString behavior. ;)

EDIT: Finally I found a reasonably obfuscated cross-browser version:

[[]+1/!1][1^1][1>>1]+({}+[])[1<<1^11>>1]+([]+!!-[])[1<<1]+[/~/+{}][+!1][-~1<<1]+([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)+(parseInt("010")<10?(1+1+1+1):0)]+([,][~1]+[])[1-~1]+[[]+{}][!1.1%1][11111.1%11.1*111e11|!1]+(/1/+1/[1<1][1%1])[1^11]+[[],[]+{}][1][+1]+(/<</[1]+[])[1/1.1&1]

This replaces the n/v section with:

([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]])[(1^11<<1)+(parseInt("010")<10?(1+1+1+1):0)]

which exploits differences in parseInt (apparently Firefox parses numbers starting with 0 as octal, while Chrome doesn't) to add 4 in Firefox's case, thus getting 'v' from 'native' in both cases (I can't find another 'v' :P).
The parseInt looks a little out of place, but that's the best I can do for now.

Peter C
  • 6,219
  • 1
  • 25
  • 37
4

For the general use-case, if character casing isn't a big concern, I might be inclined to cheat a little.

Create function "c" which turns a number 0 .. 25 into a character.

c=function(v){for(var i in window){for(var ci in i){if(parseInt(i[ci],(10+11+11)+(1<<1)+(1<<1))==(v+10)){return i[ci]}}}};

For performance reasons, pre-cache the letters, if you want.

l=[];for(var i=0; i<(11+11)+(1<<1)+(1<<1);i++){l[i]=c(i);}

In the Chrome console, the resulting array looks like this:

> l;
["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "K", "l", "m", "n", "o", "p", "q", "r", "S", "t", "u", "v", "w", "x", "y", "Z"]

So ... your v might be l[10+10+1].

Alternatively, a general solution like this:

p=(function(){10%11}+[])[1+11+(1<<1)]; // "%"
u=(function(){club=1}+[])[1+11+(1<<1)]; // "u"
vc=p+u+(0+[])+(0+[])+((111>>1)+11+10+[]); // "%u0076"
unescape(vc);

Or, for this specific problem, maybe just:

(function(){v=1}+[])[10+(1<<1)]; // "v"
svidgen
  • 13,744
  • 4
  • 33
  • 58
3

This gives a v in Chrome:

Object.getOwnPropertyNames(Object)[17][3];

And this does it in Firefox:

Object.getOwnPropertyNames(Object)[9][3]

They both pull it out of Object.prototype.preventExtensions(), so you could probably find a cross-browser way to reference that method. (It's the only 17-character name in Object.Prototype for starters.)

Feel free to build a more-obfuscated version of this and take all the credit for yourself, I'm out of time ;)

Nathan Friedly
  • 7,837
  • 3
  • 42
  • 59
2

In chrome, the expression ([]+/-/[(!!1+[])[1>>1]+(!!1+[])[1<<1^1]+(!1+[])[1|1<<1]+(!!1+[])[1^1]]) evaluates to "function test() { [native code] }", the [1^11<<1] evaluates to 23 (bitwise operators cause the variable to be truncated to 32 bits)

enhzflep
  • 12,927
  • 2
  • 32
  • 51
  • The question is `Does anyone else have an idea of how to generate a "v" that is in keeping with the original obfuscated code?` – Ian Apr 12 '13 at 18:34