IT/python

유니코드 문자열을 숫자로 변환했다가 복원하기

심량 2020. 10. 26. 12:52

문자열을 숫자로 저장했다가 다시 복원하는 방법입니다. 아래 글 내용에 나오는 코드를 고쳐봤습니다.

더보기

바보팀1님의 Hellow 난독화하기 글을 읽었습니다.

저는 python v3.8 환경을 사용하는데 여기에서는 동작하지 않아서 동작하도록 고쳐봤습니다.

버전별로 처리해보기 위해 코드를 문자화 하는데에 샐리님 블로그 글을 참조하였습니다.

# 출처: https://qkqhxla1.tistory.com/485
# 참고: https://saelly.tistory.com/171

import sys
v2 = """(lambda _, __, ___, ____, _____, ______, _______, ________:
    getattr(
        __import__(True.__class__.__name__[_] + [].__class__.__name__[__]),
        ().__class__.__eq__.__class__.__name__[:__] +
        ().__iter__().__class__.__name__[_____:________]
    )(
        _, (lambda _, __, ___: _(_, __, ___))(
            lambda _, __, ___:
                chr(___ % __) + _(_, __, ___ // __) if ___ else
                (lambda: _).func_code.co_lnotab,
            _ << ________,
            (((_____ << ____) + _) << ((___ << _____) - ___)) + (((((___ << __)
            - _) << ___) + _) << ((_____ << ____) + (_ << _))) + (((_______ <<
            __) - _) << (((((_ << ___) + _)) << ___) + (_ << _))) + (((_______
            << ___) + _) << ((_ << ______) + _)) + (((_______ << ____) - _) <<
            ((_______ << ___))) + (((_ << ____) - _) << ((((___ << __) + _) <<
            __) - _)) - (_______ << ((((___ << __) - _) << __) + _)) + (_______
            << (((((_ << ___) + _)) << __))) - ((((((_ << ___) + _)) << __) +
            _) << ((((___ << __) + _) << _))) + (((_______ << __) - _) <<
            (((((_ << ___) + _)) << _))) + (((___ << ___) + _) << ((_____ <<
            _))) + (_____ << ______) + (_ << ___)
        )
    )
)(
    *(lambda _, __, ___: _(_, __, ___))(
        (lambda _, __, ___:
            [__(___[(lambda: _).func_code.co_nlocals])] +
            _(_, __, ___[(lambda _: _).func_code.co_nlocals:]) if ___ else []
        ),
        lambda _: _.func_code.co_argcount,
        (
            lambda _: _,
            lambda _, __: _,
            lambda _, __, ___: _,
            lambda _, __, ___, ____: _,
            lambda _, __, ___, ____, _____: _,
            lambda _, __, ___, ____, _____, ______: _,
            lambda _, __, ___, ____, _____, ______, _______: _,
            lambda _, __, ___, ____, _____, ______, _______, ________: _
        )
    )
)
"""
v3 = """(lambda _, __, ___, ____, _____, ______, _______, ________, _________:
    getattr(
        __import__(True.__class__.__name__[_] + [].__class__.__name__[__]),
        ().__class__.__eq__.__class__.__name__[:__] +
        ().__iter__().__class__.__name__[______:_________]
    )(
        _, ((lambda _, __, ___: _(_, __, ___))(
            lambda _, __, ___:
                chr(___ % __) + _(_, __, ___ // __) if ___ else
                (lambda: _).__code__.co_lnotab.decode(),
            _ << ________,
            (((_____ << ____) + _) << ((___ << _____) - ___)) + (((((___ << __)
            - _) << ___) + _) << ((_____ << ____) + (_ << _))) + (((_______ <<
            __) - _) << (((((_ << ___) + _)) << ___) + (_ << _))) + (((_______
            << ___) + _) << ((_ << ______) + _)) + (((_______ << ____) - _) <<
            ((_______ << ___))) + (((_ << ____) - _) << ((((___ << __) + _) <<
            __) - _)) - (_______ << ((((___ << __) - _) << __) + _)) + (_______
            << (((((_ << ___) + _)) << __))) - ((((((_ << ___) + _)) << __) +
            _) << ((((___ << __) + _) << _))) + (((_______ << __) - _) <<
            (((((_ << ___) + _)) << _))) + (((___ << ___) + _) << ((_____ <<
            _))) + (_____ << ______) + (_ << ___)
        )).encode()
    )
)(
    *(lambda _, __, ___: _(_, __, ___))(
        (lambda _, __, ___:
            [__(___[(lambda: _).__code__.co_nlocals])] +
            _(_, __, ___[(lambda _: _).__code__.co_nlocals:]) if ___ else []
        ),
        lambda _: _.__code__.co_argcount,
        (
            lambda _: _,
            lambda _, __: _,
            lambda _, __, ___: _,
            lambda _, __, ___, ____: _,
            lambda _, __, ___, ____, _____: _,
            lambda _, __, ___, ____, _____, ______: _,
            lambda _, __, ___, ____, _____, ______, _______: _,
            lambda _, __, ___, ____, _____, ______, _______, ________: _,
            lambda _, __, ___, ____, _____, ______, _______, ________, _________: _
        )
    )
)
"""
target = ""
import os
if sys.version_info.major == 2: target = v2
elif sys.version_info.major == 3: target = v3
code = compile(target, '<string>', 'exec')
exec(code)

결과물은 hellow world! 가 출력됩니다.

이 중에 문자열을 숫자로 이를 다시 복원하는 내용이 아래와 같습니다.

def convertUnicodeStrToNum(str):
    codes = [c for c in str.encode('utf-8')]
    num = sum(codes[i] * (256 ** i) for i in range(len(codes)))
    # print(str.encode('utf-8'))
    # print(codes)
    # print(bytes(codes))
    # print(bytes(codes).decode())
    return num

def convertNumToUnicodeStr(num):
    barray = bytearray()
    while num > 0:
        barray.append(num % 256)
        num //= 256
    return barray.decode()

한글, 영문 모두 정상적으로 변환/복원됨을 확인했습니다.

간단히 설명을 하면 문자열을 바이트 배열로 만을어서 각 바이트 ascii 값을 256 을 곱해가며 더해서 하나의 큰 숫자를 만들고 복원시는 256을 나눠가며 그 나머지를 바이트 배열에 저장한 후 decode() 로 문자열로 되돌리게 됩니다.