프로그래밍 언어/python

python 데이터 통신 프로토콜 : pickle 모듈

벌게진눈 2019. 8. 13. 22:11
반응형

pickle 모듈은 python 객체를 직렬화 역질렬화하는 바이너리 프로토콜입니다.

얼핏보면 어렵다고 생각할 수 있는데 하나씩 살펴보겠습니다. pickle 모듈은 python에서만 사용 할 수 있습니다. 따라서 python 객체를 직렬화 역직렬화 한다고 하였습니다. 직렬화란 데이터 스트림에 쓰기 위해 객체에서 연속적인 데이터로 변환하는것이고 역직렬화는 반대입니다. pickle에서는 역속적인 데이터를 바이너리 형식으로 저장합니다.

사용법

pickle은 직렬화 역직렬화 방법만 알면 됩니다.

dumps

데이터를 직렬화합니다. 직렬화한 데이터를 출력해보면 바이너리형식임을 알 수 있습니다.

소스코드 :

import pickle

data = {
    'name': 'lee',
    'age': 20,
    'food_like': 'chicken',
}

binary_data = pickle.dumps(data)
print(binary_data)

실행 결과:

b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00leeq\x02X\x03\x00\x00\x00ageq\x03K\x14X\t\x00\x00\x00food_likeq\x04X\x07\x00\x00\x00chickenq\x05u.'

loads

데이터를 역직렬화 합니다. pickle로 직렬화한 데이터만 역직렬화 할 수 있으며 역직렬화한 데이터를 출력하면 문자열 형태로 출력됨을 알 수 있습니다

소스코드 :

import pickle

data = {
    'name': 'lee',
    'age': 20,
    'food_like': 'chicken',
}

binary_data = pickle.dumps(data)
print(binary_data)

result_data = pickle.loads(binary_data)
print(result_data)

출력결과 :

b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x03\x00\x00\x00leeq\x02X\x03\x00\x00\x00ageq\x03K\x14X\t\x00\x00\x00food_likeq\x04X\x07\x00\x00\x00chickenq\x05u.'
{'name': 'lee', 'age': 20, 'food_like': 'chicken'}

JSON 과 차이점

json은 텍스트 직렬화 형식이고 pickle은 바이너리 직렬화 형식입니다. 따라서 json은 데이터 자체를 사람이 읽을 수 있지만 pickle을 그렇지 않습니다. json은 python뿐만 아니라 다른곳에서도 사용할 수 있지만 pickle은 오직 python에서만 사용합니다.

그렇다면 json을 사용하면 되지 pickle은 왜있는거야? 라는 생각이 들겁니다. pickle도 장점이 있습니다. 첫번째로는 객체를 데이터에 저장할 수 있습니다.

소스코드 :

import pickle

class People:
    def __init__(self, name, age, food_like):
        self.name = name
        self.age = age
        self.food_like = food_like

    def __str__(self):
        return_str = "name = {name}, age = {age}, food_like = {food_like}"
        return return_str.format(name=self.name, age=self.age, food_like=self.food_like)

person_a = People(name='lee', age=20, food_like='chicken')
print('<origin_data>', person_a)

pickle_data = pickle.dumps(person_a)
print('<pickle_data>', pickle_data)

unpickle_data = pickle.loads(pickle_data)
print('<unpickle_data>', unpickle_data)

출력 결과 :

<origin_data> name = lee, age = 20, food_like = chicken
<pickle_data> b'\x80\x03c__main__\nPeople\nq\x00)\x81q\x01}q\x02(X\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00leeq\x04X\x03\x00\x00\x00ageq\x05K\x14X\t\x00\x00\x00food_likeq\x06X\x07\x00\x00\x00chickenq\x07ub.'
<unpickle_data> name = lee, age = 20, food_like = chicken

취약점

공식 문서에서 pickle 악의적으로 생성된 데이터는 안전하지 않으니 신뢰할 수 없는곳에서 받은 데이터는 역직렬화 하지 말라고 경고합니다.

pickle은 역직렬화 과정에서 __reduce__() 메서드를 실행하게되고 메서드에 악의적인 시스템 명령어가 있으면 큰 피해를 입을 수 있습니다.

따라서 pickle은 외부에서 접근 할 수 없는 내부 시스템간 데이터 통신에서 사용하시길 바랍니다.

반응형