www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Obfuscated code challenge

reply Phillip Meyer <phmeyer mtnd.io> writes:
See if you can figure out what this code does without running it 
;)

import std;void main(){(*["clung/locks"].tee!(function(x){return 
x;}).array.ptr).enumerate.map!(i=>mixin(cast(typeof({}))(6.8*13.3824)~"6r0d2a5
".array.chunks(2).map!(i=>[i[0].to!string~":"~39~(i[1].to!string)~'\''][0]).join(",")~"]").get(i[0],i[1])).writeln;}
Mar 13
next sibling parent tsbockman <thomas.bockman gmail.com> writes:
On Sunday, 14 March 2021 at 01:31:36 UTC, Phillip Meyer wrote:
 See if you can figure out what this code does without running 
 it ;)
Nope. I couldn't make sense of the mixin. (Also, this only works because of a compiler bug that I didn't know about.)
 import std;void 
 main(){(*["clung/locks"].tee!(function(x){return 
 x;}).array.ptr).enumerate.map!(i=>mixin(cast(typeof({}))(6.8*13.3824)~"6r0d2a5
".array.chunks(2).map!(i=>[i[0].to!string~":"~39~(i[1].to!string)~'\''][0]).join(",")~"]").get(i[0],i[1])).writeln;}
WAT?! Why is concatenating a function pointer with a char string not an error, even in system code? unittest { // This passes! assert(is(typeof(cast(typeof({})) 91) == void function() pure safe nothrow nogc)); assert((cast(typeof({})) 91) ~ "" == "["); } I filed a DMD issue: https://issues.dlang.org/show_bug.cgi?id=21711
Mar 13
prev sibling next sibling parent ag0aep6g <anonymous example.com> writes:
On 14.03.21 02:31, Phillip Meyer wrote:
 See if you can figure out what this code does without running it ;)
 
 import std;void main(){(*["clung/locks"].tee!(function(x){return 
 x;}).array.ptr).enumerate.map!(i=>mixin(cast(typeof({}))(6.8*13.3824)~"6r0d2a5 
 ".array.chunks(2).map!(i=>[i[0].to!string~":"~39~(i[1].to!string)~'\''][0]).join(",")~"]").get(i
0],i[1])).writeln;} 
First, format the code a bit: ---- import std; void main() { (*["clung/locks"].tee!(function(x) { return x; }).array.ptr) .enumerate .map!(i => mixin( cast(typeof({}))(6.8 * 13.3824) ~ "6r0d2a5 ".array.chunks(2) .map!(i => i[0].to!string ~ ":" ~ 39 ~ i[1].to!string ~ '\'') .join(",") ~ "]" ) .get(i[0], i[1]) ) .writeln; } ---- Now piece by piece: (*["clung/locks"].tee!(function(x) { return x; }).array.ptr) -> "clung/locks" ":" ~ 39 -> ":'" "6r0d2a5 ".array.chunks(2) -> ["6r", "0d", "2a", "5 "] ["6r", "0d", "2a", "5 "].map!(...).join(",") -> "6:'r',0:'d',2:'a',5:' '" From context, guess that `cast(typeof({}))(6.8 * 13.3824)` becomes char(6.8 * 13.3824) = char(91) = '['. The mixin is now trivial: mixin('[' ~ "6:'r',0:'d',2:'a',5:' '" ~ "]") -> [6: 'r', 0: 'd', 2: 'a', 5: ' '] The outer `map` effectively replaces characters in "clung/locks" with the values from the mixed in associative array. So: "clung/locks"[6] = 'r' -> "clung/rocks" "clung/rocks"[0] = 'd' -> "dlung/rocks" "dlung/rocks"[2] = 'a' -> "dlang/rocks" "dlang/rocks"[5] = ' ' -> "dlang rocks" And there it is: ---- import std; void main() { "dlang rocks".writeln; } ----
Mar 14
prev sibling parent Dukc <ajieskola gmail.com> writes:
On Sunday, 14 March 2021 at 01:31:36 UTC, Phillip Meyer wrote:
 See if you can figure out what this code does without running 
 it ;)

 import std;void 
 main(){(*["clung/locks"].tee!(function(x){return 
 x;}).array.ptr).enumerate.map!(i=>mixin(cast(typeof({}))(6.8*13.3824)~"6r0d2a5
".array.chunks(2).map!(i=>[i[0].to!string~":"~39~(i[1].to!string)~'\''][0]).join(",")~"]").get(i[0],i[1])).writeln;}
SPOILER ALERT: my result at bottom of the post. Hmm, trying this blindly. No quarantees about right result. I'll try to figure it out by refactoring in phases. First, some reformatting: ``` import std; void main() { (*["clung/locks"].tee!(function(x){return x;}).array.ptr) .enumerate .map!( i=> mixin(cast(typeof({}))(6.8*13.3824)~"6r0d2a5 ".array.chunks(2).map!(i=>[i[0].to!string~":"~39~(i[1].to!string)~'\''][0]).join(",")~"]") .get(i[0],i[1]) ) .writeln; } ``` Let's sanitize the top of the function a bit: ``` import std; void main() { "clung/locks".enumerate .map!( i=> mixin(cast(typeof({}))(6.8*13.3824)~"6r0d2a5 ".array.chunks(2).map!(i=>[i[0].to!string~":"~39~(i[1].to!string)~'\''][0]).join(",")~"]") .get(i[0],i[1]) ) .writeln; } ``` Next we move the ugliest bit to a different function: ``` import std; void main() { "clung/locks".enumerate .map!(i=>handleUglyDetails(i.index, i.value)) .writeln; } auto handleUglyDetails(size_t index, dchar value) { auto something = mixin(cast(typeof({}))(6.8*13.3824)~"6r0d2a5 ".array.chunks(2).map!(i=>[i[0].to!string~":"~39~(i[1].to!string)~'\''][0]).join(",")~"]"); return something.get(index, value); } ``` Omitting the top import and `main()` from rest of the examples as there should be no need to change it anymore. If `typeof({})` even compiles, I'd think it is `void function()`. But no, that would be totally senseless, so I quess that it just evaluates to nothing. `cast()` means unqualifying a type, but `float` is already unqualified, so I can delete the cast too. Also the mixin can be split in two: ``` auto handleUglyDetails(size_t index, dchar value) { enum firstPart = 6.8*13.3824; enum secondPart = "6r0d2a5 ".chunks(2).map!(i=>[i[0].to!string~":"~39~(i[1].to!string)~'\''][0]).join(",")~"]"); return mixin(firstPart ~ secondPart).get(index, value); } ``` Sanitizing `chunks` and `map` out: auto handleUglyDetails(size_t index, dchar value) { enum firstPart = 6.8*13.3824; enum secondPart = "6025".join(",")~"]"); return mixin(firstPart ~ secondPart).get(index, value); } ``` Which leads to: ``` auto handleUglyDetails(size_t index, dchar value) { return mixin(6.8*13.3824 ~ "6,0,2,5]").get(index, value); } ``` This makes me suspect that `6.8*13.3824` evaluates to ASCII value of '['. Using a calculator is in a way running a part of the program, so let's just check what the value is. 91. 91 / 7 == 13, meaning 91 / 6.8 == a bit over 13, just what I was expecting. So: ``` auto handleUglyDetails(size_t index, dchar value) { return [6,0,2,5].get(index, value); } ``` I assume `.get` acts the same way it acts with associative arrays, and that means this: ``` auto handleUglyDetails(size_t index, dchar value) { auto arr = [6,0,2,5]; return index < arr.length? arr[index]: value; } ``` With this definition, the `.writeln` in the main function is going to print "[6, 0, 2, 5, 103, 47, 108, 111, 99, 107, 115]" on a 64-bit platform. On 32-bit I am not sure, it is either the same result or "\x6\0\x2\x5g/locks".
Mar 15