4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

新規開発や新技術の検証、導入にまつわる記事を投稿しよう!

python でエスケープ文字の入った JSON からコンテンツを復元する

Last updated at Posted at 2023-07-20

MIME データを JSON に格納したら復元に戸惑った話。

背景

import json
import base64
import os
import sys

filepath = sys.argv[1]
filename = os.path.basename(filepath)
# 拡張子を取得
type = os.path.splitext(filename)[1][1:]


data = {}
with open(filepath, mode='rb') as file:
    img = file.read()
data['type'] = type
data['filename'] = filename
data['file'] = base64.encodebytes(img).decode('utf-8')

として、

print(data['file'])

とすると、

UEsDBBQAAAgAADAl71afAy7EKwAAACsAAAAIAAAAbWltZXR5cGVhcHBsaWNhdGlvbi92bmQub2Fz
aXMub3BlbmRvY3VtZW50LmdyYXBoaWNzUEsDBBQAAAgAADAl71YAAAAAAAAAAAAAAAAcAAAAQ29u
ZmlndXJhdGlvbnMyL2FjY2VsZXJhdG9yL1BLAwQUAAAIAAAwJe9WAAAAAAAAAAAAAAAAHwAAAENv
bmZpZ3VyYXRpb25zMi9pbWFnZXMvQml0bWFwcy9QSwMEFAAACAAAMCXvVgAAAAAAAAAAAAAAABoA
AABDb25maWd1cmF0aW9uczIvdG9vbHBhbmVsL1BLAwQUAAAIAAAwJe9WAAAAAAAAAAAAAAAAHAAA
AENvbmZpZ3VyYXRpb25zMi9wcm9ncmVzc2Jhci9QSwMEFAAACAAAMCXvVgAAAAAAAAAAAAAAABoA
AABDb25maWd1cmF0aW9uczIvc3RhdHVzYmFyL1BLAwQUAAAIAAAwJe9WAAAAAAAAAAAAAAAAGAAA

のようになる。これは、base64.encodebytes(s) によって RFC2045 (MIME) に従った 76 文字ごとに改行されたもの。

print(jsonobject["file"])

とすると

UEsDBBQAAAgAADAl71afAy7EKwAAACsAAAAIAAAAbWltZXR5cGVhcHBsaWNhdGlvbi92bmQub2Fz\n
aXMub3BlbmRvY3VtZW50LmdyYXBoaWNzUEsDBBQAAAgAADAl71YAAAAAAAAAAAAAAAAcAAAAQ29u\n
ZmlndXJhdGlvbnMyL2FjY2VsZXJhdG9yL1BLAwQUAAAIAAAwJe9WAAAAAAAAAAAAAAAAHwAAAENv\n
bmZpZ3VyYXRpb25zMi9pbWFnZXMvQml0bWFwcy9QSwMEFAAACAAAMCXvVgAAAAAAAAAAAAAAABoA\n
AABDb25maWd1cmF0aW9uczIvdG9vbHBhbmVsL1BLAwQUAAAIAAAwJe9WAAAAAAAAAAAAAAAAHAAA\n
AENvbmZpZ3VyYXRpb25zMi9wcm9ncmVzc2Jhci9QSwMEFAAACAAAMCXvVgAAAAAAAAAAAAAAABoA\n
.
.
.

となった(わかりやすいように\nの後ろに改行を入れているが、実際は巨大な1行となっている)。

これは、JSONの規格で改行を入れることができないために改行がエスケープされている。

そのうえで、


print(json.dumps(data))

として、以下のように出力されたものを使ってデータ交換を行う。

(b'tEXt', b'{"type": "odg", "filename": "x2.odg", "file":"
UEsDBBQAAAgAADAl71afAy7EKwAAACsAAAAIAAAAbWltZXR5cGVhcHBsaWNhdGlvbi92bmQub2Fz\\n
aXMub3BlbmRvY3VtZW50LmdyYXBoaWNzUEsDBBQAAAgAADAl71YAAAAAAAAAAAAAAAAcAAAAQ29u\\n
ZmlndXJhdGlvbnMyL2FjY2VsZXJhdG9yL1BLAwQUAAAIAAAwJe9WAAAAAAAAAAAAAAAAHwAAAENv\\n
bmZpZ3VyYXRpb25zMi9pbWFnZXMvQml0bWFwcy9QSwMEFAAACAAAMCXvVgAAAAAAAAAAAAAAABoA\\n
AABDb25maWd1cmF0aW9uczIvdG9vbHBhbmVsL1BLAwQUAAAIAAAwJe9WAAAAAAAAAAAAAAAAHAAA\\n
AENvbmZpZ3VyYXRpb25zMi9wcm9ncmVzc2Jhci9QSwMEFAAACAAAMCXvVgAAAAAAAAAAAAAAABoA\\n
.
.
.

さて、JSONデータを受け取った方はどうしたら RFC2045 (MIME) に従った 76 文字ごとに改行されたものに復元できるかな?

解決方法

print(jsonobject["file"].encode("utf-8").decode("unicode-escape")) 

得られるもの

UEsDBBQAAAgAADAl71afAy7EKwAAACsAAAAIAAAAbWltZXR5cGVhcHBsaWNhdGlvbi92bmQub2Fz
aXMub3BlbmRvY3VtZW50LmdyYXBoaWNzUEsDBBQAAAgAADAl71YAAAAAAAAAAAAAAAAcAAAAQ29u
ZmlndXJhdGlvbnMyL2FjY2VsZXJhdG9yL1BLAwQUAAAIAAAwJe9WAAAAAAAAAAAAAAAAHwAAAENv
bmZpZ3VyYXRpb25zMi9pbWFnZXMvQml0bWFwcy9QSwMEFAAACAAAMCXvVgAAAAAAAAAAAAAAABoA
AABDb25maWd1cmF0aW9uczIvdG9vbHBhbmVsL1BLAwQUAAAIAAAwJe9WAAAAAAAAAAAAAAAAHAAA
AENvbmZpZ3VyYXRpb25zMi9wcm9ncmVzc2Jhci9QSwMEFAAACAAAMCXvVgAAAAAAAAAAAAAAABoA
AABDb25maWd1cmF0aW9uczIvc3RhdHVzYmFyL1BLAwQUAAAIAAAwJe9WAAAAAAAAAAAAAAAAGAAA
AENvbmZpZ3VyYXRpb25zMi90b29sYmFyL1BLAwQUAAAIAAAwJe9WAAAAAAAAAAAAAAAAGAAAAENv
bmZpZ3VyYXRpb25zMi9mbG9hdGVyL1BLAwQUAAAIAAAwJe9WAAAAAAAAAAAAAAAAGgAAAENvbmZp
.
.
.

python3 は信号処理してるとムダな encode や decode が重奏して頭が痒くなりますね。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?