Develop

JSON, BSON 변환

by hooni posted Apr 23, 2013
?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

크게 작게 위로 아래로 댓글로 가기 인쇄
BSON은 Binary JSON의 약어로 JSON 포맷의 문서를 바이너리 형태로 인코딩하는 포맷이다.
MongoDB에서 제안하였으며, 주로 JSON 형태의 데이터를 통째로 저장하거나 네트워크를 통해 전송하는 용도로 사용된다.

한마디로 이렇게 이해하면 편할 수 있다.
JSON -> BSON = Serialization
BSON -> JSON = Deserialize

온라인으로 JSON <-> BSON 문서로 변환할 수 있는 사이트

JSON <-> BSON 변환의 사용 방법에 있어서 실제로는 대부분 관련 플랫폼의 라이브러리를 사용하게 되므로 그 과정은 몰라도 상관 없다.
BSON 스펙을 정의한 문서와 관련 설명은 아래 링크에서 확인할 수 있고 하단에는 실제 간단한 예제를 변환하는 과정을 설명하고 있다.

변환 방법:

예제를 보기 전에 먼저, BSON은 리틀 엔디안 방식으로 작성한다는 것에 주의한다.
(즉, 하위 바이트를 앞쪽에 쓴다.)

스펙의 예제에 나와있는 

    {"hello": "world"}

를 BSON으로 나타내면 아래와 같다.

     \x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00


변환 과정을 설명하면 다음과 같다.

    1. BSON 도큐먼트를 정의한다.

    \x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00

    전달하려는 총 바이트의 크기를 int 32로 추가한다.
    여기서는 총 22바이트(\x16)인데, 리틀 엔디안 방식으로 전달해야 하기 때문에,
    하위 바이트인 \x16을 먼저 쓴다.
    도큐먼트의 마지막을 나타내는 바이트로 마지막에 \x00 을 추가한다.


    2. 데이터의 타입을 정의한다.

    \x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00

    키에 해당하는 데이터의 타입을 나타내는 코드를 추가한다.
    여기서는 "world"이고, UTF-8 string 이기 때문에 \x02를 추가했다.


    3. 키값을 정의한다.

    \x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00    
    
    키 값은 UTF-8 인코딩된 문자열과 문자열이 끝났음을 알려주는 \x00을 추가한다.


    4. 데이터를 정의한다.

    \x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00    

    string을 표기할 때에는 초기 4바이트에 종료 문자(\x00)을 포함한 문자열의 길이를 추가한다.
    여기서, 5바이트 크기인 "world"와 종료문자를 포함해 \x06을 길이로 추가했고,
    리틀 엔디안으로 표기해야하기 때문에 "\x06\x00\x00\x00" 와 같이 작성했다.


    5. 문서의 마지막임을 알린다.

    \x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00

    1번에 설명했던 것처럼, BSON 도큐먼트가 종료되었음을 알리는 종료 문자를 마지막에 추가한다.




다른 예제로, 배열을 포함한 문서의 변환 과정을 설명하면 다음과 같다.

    {
      "BSON": [
       "awesome", 5.05, 1986
      ]
    }

    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

순서대로 읽어보면 아래와 같다.


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00


    총 길이 49바이트의 BSON 문서이고,


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    데이터는 Array 타입이고,


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    키 값은 BSON!


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    BSON에서 Array는 인덱스를 키로 갖는 문서와 동일하게 취급한다.
    따라서, 위의 예제에서의

        [ "awesome", 5.05, 1985 ]

    는 아래와 같은 도큐먼트라 생각하고 변환하면 된다.

        { "0": "awesome", "1": 5.05, "2": 1985 } 

    문서의 처음은 Array 데이터의 총 길이인 38바이트를 리틀 엔디안으로 표기한 \x26\x00\x00\x00 이다.


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    첫 번째 키에 해당하는 데이터의 타입은 string이다.


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    키 값은 0이고,


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    데이터의 크기는 종료 문자를 포함해 8바이트이다.


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    문자열의 값은 awesome


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    두 번째 데이터는 double 타입의 숫자이고,


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    키 값은 "1"이다.


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    BSON에서 double은 IEEE 754의 기준에 따라 8바이트로 표기한다.
    (5.05를 바이너리 데이터로 전환하는 게 잘 되지 않네요.-_- 과정을 아시는 분은 좀 알려주세요~~)


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    세 번째 데이터는 4바이트 크기의 정수이다.


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    키 값은 "2"이고,


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    1986을 4바이트로 표기한다.


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    Array를 포함한 문서가 종료되었음을 알리고,


    \x31\x00\x00\x00\x04BSON\x00
    \x26\x00\x00\x00\x020\x00\x08\x00\x00\x00awesome\x00\x01
    1\x00\x33\x33\x33\x33\x33\x33\x14\x40\x102\x00\xc2\x07\x00\x00\x00\x00

    전체 데이터가 종료된 것을 알린다.