The presentation from SPbPython community / PiterPy meetup.
The presentation tells about one idea how it is possible to perform an obfuscation of numbers in Python.
Types comparison >>> {} > [] # i.e. 'd' > 'l' ([d]ict > [l]ist) False >>> [] > {} # i.e. 'l' > 'd' ([l]ist > [d]ict) True Python 2 only! CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don’t support proper comparison are ordered by their address.
Fixed in Python 3 >>> {} > [] Traceback (most recent call last): File "", line 1, in TypeError: '>' not supported between instances of 'dict' and 'list' Let's use the following approach in Python 3: >>> [] < [] False
True and False As bool type inherits from int, bool values explicitly considered as integer, it's possible to get 0 and 1 from False and True. >>> False == 0 True >>> True == 1 True NB: In Python 2 it is possible to reassign True and False. In Python 3 True and False are keywords and always equal to 1 and 0.
Numbers Other numbers can be obtained by applying logical operations E.g. "~" = bitwise NOT, or "<<" bitwise left shift. For example 2: 2 = -(-2) = -(~1) >>> 2 == -(-2) == -(~1) True
Converting numbers Let’s take 16 as a base (i.e. hexadecimal numeral system) therefore each decimal number can be obtained by sum of multiplications of each decimal digit of a number by 16. Example: 17 = (16+1) 42 = (2*16+10) 123 = (7*16+11) 1000 = ((3*16+14)*16+8)
Converting numbers def get_number(num): r = '' if num > numbers_count: if num // numbers_count > 1: if num % numbers_count == 0: r += '(%s*%s)' % (get_number(num // numbers_count), numbers_count) else: r += '(%s*%s+%s)' % (get_number(num // numbers_count), numbers_count, num % numbers_count) else: r += '(%s+%s)' % (numbers_count, get_number(num - numbers_count)) else: r = '%s' % num return r def convert_nums(s): res = s for n in range(numbers_count, -1, -1): res = res.replace(str(n), nums[n]) res = res.replace('+-', '-') return res
Other examples Negative numbers: change the sign in front of the parentheses Possible errors for huge numbers :( Traceback (most recent call last): File "", line 1, in File "", line 8, in get_number ... File "", line 3, in get_number RecursionError: maximum recursion depth exceeded in comparison _push: parser stack overflow Traceback (most recent call last): File "obfuscation.py", line 51, in print(eval(obfuscated)) MemoryError