📜 ⬆️ ⬇️

Solving the picture from the Intel company Twitter

There is a horror story with an incredible number of underscores, lambdas and an extremely rare __import__ function:



What kind of beast and what does he do?
')
Of course, we can, like normal people, retype the code into the interpreter and see what happens. But since the time is long past midnight, it's more interesting to deal with your hands.

The code will still have to be rewritten. If you are afraid of succumbing to the temptation to launch - write better on a piece of paper.

So, to begin with, we will try to display all this without devilish tilting, while we will try (as far as possible) to make the text readable:

getattr( __import__(True.__class__.__name__[1] + [].__class__.__name__[2]), ().__class__.__eq__.__class__.__name__[:2] + ().__iter__().__class__.__name__[5:8] ) ( 1, ( lambda _, __: _(_, __) )( lambda _, __: chr(__ % 256) + _(_, __ // 256) if __ else "", 882504235958091178581291885595786461602115 ) ) 

We are far from PEP8, and it’s not worth sending a review to the code yet, but it’s already much better.

There is a getattr, so the first brackets "return" the function to us, and the second will be a list of arguments.
The first argument getattr takes an object, the second an expected attribute. Let's start with the object.

In fact, the __import__ function is what the familiar “from X import Y as Z” turns into. The function is very rare and you will not meet its use in a “combat” situation at every corner. You can learn more about its device in the documentation , but to speed up the process, we will declare that in our case this function is similar to the expression:

 from True.__class__.__name__[1] + [].__class__.__name__[2] import ().__class__.__eq__.__class__.__name__[:2] + ().__iter__().__class__.__name__[5:8]) 

The first part is simple - we go up the stairs. For the needs of True and False in python there is a special type of “bool”, and this is what the __class __.__ name__ chain will give us back. Take the first element, it will be the letter "o".
The search for the second letter is not much harder - [] is a list, the list is “list”, “list” [2] is “s”.
The first part of the mini-puzzle is successfully solved:

 from os import ().__class__.__eq__.__class__.__name__[:2] + ().__iter__().__class__.__name__[5:8]) 

We deal with the second part. "()" is a tuple, i.e. tuple, __eq__ is the "magic" wrapper for the comparison operator "==". Here we first come to a known substance, if we think that "== .__ class__" is some kind of "function". In reality, this is a wrapper_descriptor that no one would have noticed in another case, but here it is very important. Unfortunately, I am not privy to the secret of class naming for embedded magic methods, so we hope for its disclosure in the comments. Take the “wrapper_descriptor” [: 2] cut, get “wr”.

Then you can not understand, because the module "os" has only one method, starting with "wr" and this, obviously, write.
You can do the analysis of the second part of this word on your own, nothing complicated.

 from os import write 

As we found out earlier, now we have to call the write function with not very clear arguments.

 from os import write write(1, ( lambda _, __: _(_, __) ) ( lambda _, __: chr(__ % 256) + _(_, __ // 256) if __ else "", 882504235958091178581291885595786461602115 ) ) 

The first argument should go to the descriptor in which we are going to write. In our case, this is 1, and this is ... stdout! Simply put, our os.write will work like print.

Then the following happens: the first anonymous function is wrapped in parentheses, which means it is called here.

To better understand what she is doing, we will write it down as an ordinary method, after thinking a little about the contents.

 lambda _, __: _(_, __) 

We take two arguments, then the __call__ method is called first. It is logical to assume that the first argument is a function, then:

 def function_one(inner, argument): return inner(inner, argument) 

Nothing happens except for “forwarding” the arguments to the function passed to us by the first parameter. What is this feature?

 lambda _, __: chr(__ % 256) + _(_, __ // 256) if __ else "", 

We see the chr method, therefore, we convert the number to a symbol. Let's rewrite humanly:

 def function_two(inner, ordC): if ordC: return chr(ordC % 256) + inner(inner, ordC // 256) else: return "" 

Carefully looking at these things, we realize that the following happens: we take a number, divide it with the remainder by 256, save the remainder as a symbol, and recursively pass the partial until the number is less than 256 (i.e. // 256 == 0). Not so cunning.

The huge number we give is written above. Since we have dealt with everything, let's try to put it all together and write something similar on a human python.

 from os import write def recursive_print(number): if number: write(1, chr(number % 256)) recursive_print(number // 256) else: return recursive_print(882504235958091178581291885595786461602115) 

And although in Russia another day is set aside for mother's day, this advice is worth following.

Source: https://habr.com/ru/post/257757/


All Articles