programing

JSON에서 base64 인코딩된 데이터 직렬화

telebox 2023. 3. 23. 22:36
반응형

JSON에서 base64 인코딩된 데이터 직렬화

데모용 데이터 생성을 자동화하는 스크립트를 작성하고 있는데 JSON에서 데이터를 시리얼화해야 합니다.이 데이터의 일부는 이미지이기 때문에 base64로 인코딩했습니다만, 스크립트를 실행하려고 하면 다음과 같이 표시됩니다.

Traceback (most recent call last):
  File "lazyAutomationScript.py", line 113, in <module>
    json.dump(out_dict, outfile)
  File "/usr/lib/python3.4/json/__init__.py", line 178, in dump
    for chunk in iterable:
  File "/usr/lib/python3.4/json/encoder.py", line 422, in _iterencode
    yield from _iterencode_dict(o, _current_indent_level)
  File "/usr/lib/python3.4/json/encoder.py", line 396, in _iterencode_dict
    yield from chunks
  File "/usr/lib/python3.4/json/encoder.py", line 396, in _iterencode_dict
    yield from chunks
  File "/usr/lib/python3.4/json/encoder.py", line 429, in _iterencode
    o = _default(o)
  File "/usr/lib/python3.4/json/encoder.py", line 173, in default
    raise TypeError(repr(o) + " is not JSON serializable")
  TypeError: b'iVBORw0KGgoAAAANSUhEUgAADWcAABRACAYAAABf7ZytAAAABGdB...
     ...
   BF2jhLaJNmRwAAAAAElFTkSuQmCC' is not JSON serializable

제가 알기로는 base64-encoded-anything(이 경우 PNG 이미지)은 문자열이기 때문에 시리얼라이제이션에 문제가 있을 수 있습니다.제가 무엇을 빠뜨리고 있나요?

데이터형에 주의해야 합니다.

바이너리 이미지를 읽으면 바이트를 얻을 수 있습니다.이러한 바이트를 base64 로 부호화하면, 다시 ... 바이트가 됩니다(b64encode 의 메뉴얼을 참조해 주세요).

json은 원시 바이트를 처리할 수 없기 때문에 오류가 발생합니다.

방금 몇 가지 예를 썼는데, 코멘트가 도움이 되었으면 합니다.

from base64 import b64encode
from json import dumps

ENCODING = 'utf-8'
IMAGE_NAME = 'spam.jpg'
JSON_NAME = 'output.json'

# first: reading the binary stuff
# note the 'rb' flag
# result: bytes
with open(IMAGE_NAME, 'rb') as open_file:
    byte_content = open_file.read()

# second: base64 encode read data
# result: bytes (again)
base64_bytes = b64encode(byte_content)

# third: decode these bytes to text
# result: string (in utf-8)
base64_string = base64_bytes.decode(ENCODING)

# optional: doing stuff with the data
# result here: some dict
raw_data = {IMAGE_NAME: base64_string}

# now: encoding the data to json
# result: string
json_data = dumps(raw_data, indent=2)

# finally: writing the json string to disk
# note the 'w' flag, no 'b' needed as we deal with text here
with open(JSON_NAME, 'w') as another_open_file:
    another_open_file.write(json_data)

대체 솔루션으로는 커스텀 인코더를 사용하여 데이터를 즉시 인코딩하는 방법이 있습니다.

import json
from base64 import b64encode

class Base64Encoder(json.JSONEncoder):
    # pylint: disable=method-hidden
    def default(self, o):
        if isinstance(o, bytes):
            return b64encode(o).decode()
        return json.JSONEncoder.default(self, o)

이를 정의하면 다음 작업을 수행할 수 있습니다.

m = {'key': b'\x9c\x13\xff\x00'}
json.dumps(m, cls=Base64Encoder)

다음을 실현합니다.

'{"key": "nBP/AA=="}'

제가 무엇을 빠뜨리고 있나요?

이 에러는, 다음과 같이 외치는 것입니다.binary는 JSON 시리얼화 할 수 없습니다.

from base64 import b64encode

# *binary representation* of the base64 string
assert b64encode(b"binary content")                 == b'YmluYXJ5IGNvbnRlbnQ='

# base64 string
assert b64encode(b"binary content").decode('utf-8') ==  'YmluYXJ5IGNvbnRlbnQ='

후자는 확실히 "JSON serializable"입니다.이는 바이너리의 base64 스트링 표현이기 때문입니다.b"binary content".

언급URL : https://stackoverflow.com/questions/37225035/serialize-in-json-a-base64-encoded-data

반응형