티스토리 뷰

반응형

1. Protocol Buffer란?

  • 데이터를 직렬화하기 위한, Google의 언어 / 플랫폼 중립적인 기술
  • Data가 어떻게 구조화되어야하는지 한 번만 정의하면, 자동 생성된 소스 코드를 통해 다양한 데이터 스트림과 언어에서 구조화된 데이터를 쉽게 쓰고 읽을 수 있다. (= 사용할 수 있다.)

 

2. Encoding

i). 다음과 같이 데이터 구조를 정의했다고 가정하자.

  • Test1이라고 이름 붙인 구조는 정수형 변수 a를 사용한다.
  • 이를 Java에서 모델로 표현했다면, 다음과 같은 형태가 된다.
public class Test1 {
  private int a;
}
  •  해당 Java 모델을 통해 JSON 문서를 주고 받는다면, 다음과 같은 형식일 것이다.
{
  a: [int]
}
  • 즉, 실제로 주고 받는 정보의 형식은 JSON이며, 이러한 JSON 형식의 문서를 활용하기 위한 데이터 구조로 'Test1'이라는 모델을 정의한 셈이 된다. 

 

ii). ProtoBuf에서는?

  • i).의 설명에 따르면, 프로그래밍 언어별로 모델을 정의하고 사용하여야만 한다.
  • Protocol Buffer를 활용할 경우, 언어 / 플랫폼 중립적인 모델의 정의가 가능해진다. 
  • 예시는 다음과 같다.
message Test1 {
  optional int32 a = 1;
}
  • 이 때, a는 int32 형 데이터이며, 직렬화에 활용하기 위한 필드 번호는 1번이다.
    • a의 값을 1로 초기화한다는 의미가 아님!

 

iii). 예시

  • JSON 모델의 a 변수에 정수 150을 넣어 전송한다고 가정하자.
{
  "a": 150
}
  • 이는 인코딩된 경우, 9byte로 계산된다(특수 문자 {"":} 5 + 영문 1 + 숫자 3)
    • 확인 필요

 

  • 이를 ProcolBuffer의 Test1 메시지를 통해 직렬화할 경우, 다음의 인코딩 결과를 얻게 된다.
  • 08 96 01 : 0000 1000 / 1001 0110 / 0000 0001
  • 결과 3byte로 계산되며, Protocol Buffer를 활용해 직렬화된 데이터의 크기가 작아지게 된다!

 

iv). 인코딩 순서

  1. 첫 byte는 다음과 같이 산출한다.
    • (필드 번호) 5자리 + (wire type) 세자리
    • 00001 000 = 0000 1000 = 08 
  2. 150을 이진수로 변환한다 : 128 + 16 + 4 + 2 = 1001 0110
  3. msb를 버린 것을 가정하고 정리 : 000 0001 001 0110
    • 뒤부터 7자리를 세면 쉽다
  4. 순서 변경 : 001 0110 000 0001
    • least significant group이 먼저 오도록 변경
  5. msb 수정 : 1001 0110 0000 0001 (96 01)
    • msb는 뒷 byte가 있는 경우 1, 없는 경우 0
  6. 1.의 결과에 2.의 결과를 붙인다 : 08 96 01

 

  • 300의 경우 : 
    1. 첫 byte : 08
    2. 300을 이진수화 : 1 0010 1100
    3. msb를 버린 것을 가정하고 정리 : 000 0010 010 1100
      • 뒤부터 7자리를 세면 이해하기 쉽다
    4. least significant group이 먼저 오도록 수정 : 010 1100 000 0010
    5. 뒷 byte가 있음을 알리기 위해 byte별 msb 수정 : 1010 1100 0000 0010

 

v). 디코딩 순서

  • 08 96 01을 디코딩하면,
  • 08
    • 0000 1000
    • msb 제거 : 000 1000
    • 순서 변경 : 1000 000(wire type = 0)
    • 1000 > rigth shift 3 : 0001 > tag 1인 값은 varInt형이며
  • 96 01
    • 1001 0110 0000 0001
    • 001 0110 / 000 0001
    • 000 0001 / 001 0110
    • 뒤에서부터 여덟자리 : 1001 0110 > 값은 150이다.

 

  • 08 AC 02를 디코딩하면,
    • 0000 1000
    • 000 1000 : wire type 0
    • 1000 >> 3 : 필드 번호 1
  • AC 02 : 1010 1100 0000 0010
  • msb 제거 : 010 1100 000 0010
  • 순서 변경 : 000 0010 / 010 1100
  • 붙여 읽기 : 1 0010 1100 > 256 + 32 + 8 + 4 = 300

 

번외 : 

message Person {
  // 생략
  int64 num = 2;
}
  • num 1337이면?

인코딩

  • 1337 > 539 > 0101 0011 1001 (2진수 변환)
  • 000 1010 / 011 1001 (뒤에서부터 7자리)
  • 1011 1001 / 0000 1010 (순서 바꾼 후 MSB 추가)
  • > 10 B9 0A

 

10 B9 0A 디코딩

  • 0001 0000 > 00010 000 > wiretype / 필드 번호 2
  • B9 0A > 1011 1001 0000 1010
    • 011 1001 / 000 1010
    • 000 1010 / 011 1001
    • 101 0011 1001 > 1337
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
글 보관함