이것저것하는게 많은데 틈틈이 블록체인 공부를 하고 있다. 통신을 위해서 protobuf를 사용하는데 이 때 직렬화를 통해서 바이너리로 인코딩을 한다. 내가 입력한 100 이나 바이너리 100 이나 똑같은 것 아닌가? 라는 가벼운 생각을 했다. (전공이 컴퓨터공학임에도 ㅋㅋㅋ...) 여튼 궁금해서 찾아봤다. 내가 인간이고 인간이 읽기 쉬운 데이터와 컴퓨터에게 좋은 데이터는 다른 형태를 띄고 있다는 것을 간과했다..
바이너리로 인코딩하는 이유를 알면 왜 protobuf가 바이너리로 직렬화하는지 알 수 있을 것이다.
컴퓨터에서 모든 것은 bit와 byte다.(8bit == 1byte) 8bit를 가지고 만들 수 있는 숫자는 0~255 인데 이걸로 컴퓨터는 뭘 할 수 있는데? 바로 문자를 표현할 수 있다. 이게 아스키 코드다.
예를 들어 'A'를 표현하고 싶다면 A에 해당하는 아스키 숫자 65를 바이너리로 저장한다. 01000001.
아스키코드
그래 뭐 알겠다. 우리가 보는 65와 컴퓨터의 65는 뭔 차이인데?
아주 큰 차이가 있다. 우리는 65를 그대로 컴퓨터에 저장했다고 생각한다. 그런데 우리는 두 가지 숫자를 입력한 것이다. '6' , '5' 이 때 아스키 코드는 두개가 사용된다. 그래서 2byte가 사용됐다.
컴퓨터 입장에서 65는 그냥 01000001로 저장할 수 있는데 사람이 입력한 것은 6,5로 나눠서 저장하게 되는 것이다.
더 나아가서 우리가 숫자 4,000,000,000을 저장한다고 치자. 사람은 10개의 아스키 코드를 사용하게 된다. 컴퓨터는? 4byte만 사용하면 된다.
위와 같이 숫자를 컴퓨터 저장 공간에 저장하는 것은 공간이 효율적이다.
바이너리 포멧은 매우 효과적이지만 우리는 왜 항상 쓰지 않는가?
사람이 4byte 숫자를 읽을 때 (1,0이 32개..!) 이게 아스키로 저장된 4byte문자인지 숫자인지 알 방도가 없다. 그런데 10개의 아스키 코드로 4000000000을 보면 숫자라는걸 알 수 있다.
4000000000을 2000000000으로 변경하고 싶다면 이에 해당하는 이진수 표현법을 생각해야 한다. 그런데 아스키 코드에서는? 4를 2로 변경하면 된다.
숫자를 2진수로 표현하면 이상적으로는 3의 계수를 절약할 수 있습니다(4바이트 숫자는 10바이트의 텍스트를 나타낼 수 있음). 그러나 이는 표현하고자 하는 숫자가 크다는 가정 하에 이루어진 것입니다(999와 같은 3자리 숫자는 4바이트 숫자보다 ASCII로 표현하는 것이 더 낫습니다). 마지막으로, ASCII는 실제로 바이트당 7비트만 사용하므로 이론적으로 ASCII를 함께 패킹하면 1/8 또는 12%의 이득을 얻을 수 있습니다. 하지만 이런 방식으로 텍스트를 저장하는 것은 일반적으로 번거로울 수 있습니다. 출처
바이너리 파일이 효율적인 이유는 1바이트의 8비트를 모두 사용할 수 있지만 대부분의 텍스트는 패턴이 고정되서 사용하지 않는 공간이 남기 때문입니다. 그러나 텍스트 데이터를 압축하면 공간을 줄이고 효율적으로 만들 수 있습니다.
여튼 우리가 항상 효율적이란 이유로 바이너리 포멧을 사용하지는 않는다. 효율은 저장공간, 코딩하는 노력, 시간 등등이 포함되기 때문이다. 이를 다 포함해서 바이너리를 사용할 때 이점을 가지는 것이 무엇일까?
PNG는 바이너리 포멧을 사용하는데 작은 이미지 파일을 만들 때 데이터 효율성이 중요하기 때문이다.
비즈니스를 위해서 사용하기도 한다. 바이너리를 읽고 리버스 엔지니어링을 하기 어렵기 때문이다.
데이터 통신할 때, 통신 데이터가 많다는 것은 더 많은 리소스가 사용된다는 뜻이다. 데이터를 압축하기도 하고 직렬화하고 역직렬화 하는 경우가 많다. 이럴 때 사용한다. 특히 서버 클라이언트, 블록체인 네트워크 상에서는 더욱 중요하다. 데이터 무결성과 보안, 효율성을 확보하기 위해서 바이너리로 포멧을 바꾸고 직렬화하는 경우가 필요하다.
바이너리는 효율적이다. 사람이 읽기는 어렵지만 컴퓨터에게는 큰 문제가 없고 오히려 좋다. 코딩할때는 직렬화하지 않고 송신할 때 직렬화하고 수신할 때 역직렬화하면 컴퓨터도 좋고 나도 좋고 네트워크도 좋아한다.