인코딩 vs 디코딩 정확하게 이해하기
본문 바로가기
겅부합시다

인코딩 vs 디코딩 정확하게 이해하기

by 쏠수있어ㅤ 2022. 8. 5.
반응형

 

 

 

이번 개발 프로젝트를 하며 인코딩, 디코딩을 많이 접했다. 개발을 진행하면서 많이 답답했었다. 기본 지식이 없는 상태에서 어떤 인코딩인지 어떻게 디코딩을 해서 써야할지 코드를 겨우 찾아 썼지만서도 제대로 이해하며 코드를 작성한 건 아니였기 때문이다. 이제야 겨우 한숨 돌리며 제대로 이해해보는 인코딩, 디코딩! 

 

 

 

인코딩이란 ? 

사람이 인지할 수 있는 문자(언어)를 약속된 규칙에 따라 컴퓨터가 이해하는 언어 (0과 1)로 이루어진 코드로 바꾸는 것을 통틀어 일컫는다. 즉, 인코딩 encoding이란 정해진 규칙에 따라 코드화, 암호화, 부호화하는 것을 말한다. 이렇게 인코딩을 하는 이유는 정보의 형태 표준화, 보안, 저장 공간 절약 등을 위해서이다. 

 

예를 들어 친구에게 "비트코인 지금 당장 사야해"라도 말하고 싶은데 다른 사람들은 내 말을 이해하지 못하면 좋겠고, 내 친구만 이해할 수 있도록 하고 싶을 때 내가 전할 말을 "encoding"하면 된다. 그리고 코드화된 말을 들은 친구가 서로 공유된 규칙에 따라 디코딩, decoding을 하여 무슨 말인지 이해할 수 있다. 

 

영화에 많이 나오는 모스 부호 (Morse Code)도 대표적인 인코딩 방식이다. 

 

인코딩 종류는 여러가지가 있는데 크게 1) 문자 인코딩 2) 사진 & 오디오 & 비디오 인코딩 이렇게 나누어진다. 

 

 

문자 인코딩, Character Encoding 

문자 인코딩은 "문자"를 "bytes, 바이트"로 인코딩 (변환) 시킨다. 컴퓨터는 오직 binary data 만 이해하기 때문에 우리 인간들이 사용하는 문자(언어)들은 numeric codes, 숫자 표현 코드로 변환되어야 한다. 

* binary data란 이진 숫자 시스템으로 표현된 데이터의 한 타입이다. 

 

문자 인코딩의 종류에는 6가지가 있다. 

 

1. HTML Encoding

HTML 인코딩은 HTML 페이지를 올바르게 나타내기위해 사용되는 인코딩의 종류이다. 

 

2. URL Encoding

URL (Uniform Resource Locator) 인코딩은 인터넷을 통해 전송될 수 있는 포멧으로 문자를 변환시키는 인코딩 방식이다. ASCII character-set을 사용하여 인터넷으로 URL을 보내는데 사용된다. 개발 중 가끔 url에 한글이 들어가 있으면 에러가 나는 경우가 있었는데 URLEncode()를 사용해서 해당 글자를 인코딩해주면 해결되었었따. 영어와 달리 한글은 Ascii 문자가 아니어서 한글과 같이 Non-Ascii 문자를 %~ 퍼센트 기호 + 16진수 숫자로 인코딩하여 보내주어야 한다. Non-Ascii문자를 %~으로 나타내어 URL 인코딩을 퍼센트 인코딩이라고 불르기도 한다. 

 

 

 

3. UNICODE Encoding

유니코드 인코딩은 많은 인코딩 방법들 중 기준이 되는 인코딩이다. (a universal character set) 

전 세계 대부분의 언어 또는 writing systems 을 인코딩할 수 있고 표현하고 다룰 수 있다. 유니코드는 글자를  나타내기 위해8, 16, 32 비트를 사용한다. 여기서 8비트를 사용하는 UTF-8은 가장 많이 보고 들어본 인코딩 방식이다. 

 

* UTF-8 Encoding

유니코드 인코딩 중의 가장 기준이 된다. 8bit을 기본으로 사용한다. Ascii 코드와 직접적으로 호환가능하여 레거시 apps 업그레이드를 할 경우 거의 Utf-8을 선택한다. 대부분의 경우 Utf-8은 가작 적은 메모리를 사용한다. 하지만 각 글자의 넓이를 보장할 수 없어 1,2,3 또는 4의 넓이를 가지게 되어 string조작에 어려움이 있다. 

 

* UTF-32 Encoding

UTF-32은 UTF-8과 반대로 최대 메모리를 사용한다. 각 글자는 고정된 4bytes wide 넓이를 가지고 있어 string 조작이 훨씬 수월하고 간편해진다. 한 예로 string bytes의 length길이로 아주 간단하게 글자의 수를 구할 수 있다. (Utf-8은 불가능)

 

* UTF-16 Encoding

UTF-16이 세 번째에 설명하는 이유는 Utf-8과 Utf-32을 반반 섞은 인코딩이기 때문이다. UTF-16은 대부분의 글자를 고정된 넓이(a fixed-width) 16bit 값으로 한다. 중국어 기호나 음악 음표나 다른 특수한 케이스가 아닌 이상 우리는 Utf-16으로 인코딩 된 글자가 모두 각각 16bits wide를 가진다고 생각할 수 있다. 이는 Utf-32보다 적은 매모리를 쓴지만 Utf-8보다는 항상 더 큰 메모리를 사용한다. 결론적으로 그렇다고 Utf-16이 최고의 방법이라고 할 수 없는 것이 아직 Utf-8문제와 같은 각 글자의 넓이를 항상 알 수 없다는 단점이 존재하기 때문... 

 

 

UTF 8, 16, 32 - 그럼 대체 무엇을 써야하지 ??? 

위 세가지 방식 모두 같은 character set을 인코딩 할 수 있지만 단지 byte sequences에 따라 각 글자를 표현해 내는 것이 다를 뿐이다.  windows는 Utf-16을 내부적으로 사용하고 Linux는 조금 다양하게 사용하지만 일반적으로 Utf-8을 사용한다. (때문에 각 os에 맞는 방식을 선택하는 것이 좋음) 

 

 

 

4. Base64 Encoding

Base64 인코딩은 binary data를 동등한 Ascii 문자 (text) 로 인코딩하는데 사용된다. Base64 인코딩은 mail system에서 사용되는데 이는 SMTP와 같은 메일 시스템이 오직 Ascii textual data만을 받아들일 수 있기 때문에 binary data를 읽을 수가 없기 때문이다. 만약 어떤 파일이나 이미지가 base64인코딩없이 이동된다면 mail system은 binary data를 처리할 수 없기때문에 못쓰게 된다.  또한 간단한 HTTP 인증에도 쓰이기도 한다. 

 

base64 인코딩은 binary data를 cookies 또는 다른 매개변수로 이동시키는데에도 사용된다. 데이터를 읽을 수 없도록 만들어 tampering (부적절한 정보 수정) 을 방지하기 위함이다.

 

Base64 는 데이터를 3바이트의 블록들로 나타낸다. 각 바이트는 8비트를 포함하므로 3x8= 24비트를 나타낸다.이 24비트들은 6비트의 4개의 그룹으로 쪼개지는데 각각의 그룹 (chucks)은 동등한 Base64 값으로 변환된다. 

 

 

 

 

5. ASCII Encoding

ASCII = American Standard Code for Information Interchange 는 1963년도에 처음 발표된 세계 첫 문자 코드이다. 라틴 문자, 숫자, 일부 특수 문자를 (2^7) 0~127까지의 숫자에 128개를 1:1 대응시킨 코드이다. 대부분의 현대 문자 인코딩 방식들은 모두 아스키 코드를 기본으로 하지만 아스키 코드보다 훨씬 더 많은 문자(언어)들을 표현해낼 수 있다.

 

Ascii 는 7비트를 사용한 single byte 인코딩이다. Ascii 파일 안의 각각의 알파벳, 숫자, 특수 기호는 모두 7비트의 binary number로 이루어져 있다. 현재는 컴퓨터가 8bits = 1byte 로 표준화되어 7bits를 사용하는 아스키코드는 앞에 0을 붙여 8bits으로 인코딩을 진행한다. 

 

 

 

6. Hex Encoding (or base16)

Hex 인코딩은 정식적인 표준이 아니라서 다른 의미들을 가지고 있을 수 있지만 wiki에서 정의한 내용으로 정리해보려고 한다.

Hex 인코딩은 각각의 byte를 두 자리의 base-16인코딩으로 변환하고 일반적으로 이를 다시 Ascii로 인코딩한다. 비효율적이지만 binary data를 plain text로 나타낼 때 자주 사용되는 방식이다. 

 

Unix 기반이면 xxd가 보통 설치되어 있어서 hex encoding & decoding을 테스트해볼 수 있다. 

 

1) "Hex encoding test"를 Hex 인코딩하기 

2) Hex 인코딩이 되어 있는 값을 디코딩하기 

 

Base64 vs Hex 

여기서 궁금한 점 ! Base64 인코딩도 똑같이 binary data를 text로 변환하고 위의 Hex (base16)인코딩도 binary를 text로 변환한다면 두 인코딩 방식은 어떤 차이점이 있을까? 

 

-> base64와 hex(base16)은 사실 어떻게 bytes 바이트를 나타내는지가 다를 뿐이다. Base64는 3bytes 당 4 자를 사용하고 Hex는 1byte에 2 자를 사용한다. 즉, Base64가 hex보다 더 효율적이다. 만약 100k file이 있다면 hex로는 200k, base64로는 133K가 된다. 많은 경우에 이 차이는 크게 작용하지 않지만 공간 효율을 따져봐야하는 개발 중이라면 base64가 더 적합하다고 할 수 있다. 

 

 

 

 

사진 & 오디오 & 비디오 인코딩 

 

사진, 오디오 그리고 비디오 인코딩은 저장 공간을 절약하기 위해 사용된다. 이러한 media 파일은 더 효율적이고 압축된 포멧으로 인코딩이 진행된다. 이렇게 인코딩이 진행된 파일은 여전히 인코딩 이전의 파일과 같은 내용을 담고 있지만 압축되어 사이즈가 다르다. 덕분에 공간을 더욱 효율적으로 사용하고 mail이나 또는 다운로드 방식으로 쉽게 이동/전달이 가능하다.

 

 

 

 

 


 

 

 

 

디코딩이란?

 

디코딩, decoding 이란 인코딩의 반대되는 개념으로 복호화, 역코드화의 의미를 가지고 있다. 저장 공간 효율화, 보안 등의 이유로 인코딩을 한 데이터를 다시 디코딩을 해서 사용할 수 있다. 위에서 설명한 여러 인코딩 방식들이 있었는데 어떠한 특정 인코딩 방식으로 인코딩이 된 데이터를 동일한 방식으로 디코딩을 해주면 데이터를 읽어올 수 있다. 

 

인코딩 - 디코딩 - 인코딩 - 디코딩 -.... 이렇게 인코딩과 디코딩은 순환 구조를 가지고 있다. 

 

Encoders & Decoders에 대한 개념을 잘 설명한 영상 👇👇

https://www.youtube.com/watch?v=feBvhLFQEDk 

 

 

 

 

인코딩과 디코딩을 쉽게 바로바로 볼 수 있는 사이트 👇👇

바로 눈에 보여서 좀 더 쉽게 인코딩, 디코딩을 이해할 수 있었다.

 

https://r12a.github.io/app-encodings/

 

Encoding converter

show all the characters in: Select... big5 euc-jp iso-2022-jp shift_jis euc-kr gb18030 (index only) gbk koi8-r koi8-u windows-1250 windows-1251 windows-1252 windows-1253 windows-1254 windows-1255 windows-1256 windows-1257 windows-1258 macintosh ibm866 wind

r12a.github.io

 

 

인코딩 & 디코딩에 대해 조금은 이해가 된 것 같다. 그래도 아직 100%는 아닌 것 같아서 다음 포스팅에 더 정리를 해봐야겠다.

 

혹시 내용 중에 잘못된 내용이 있다면 댓글로 알려주시면 감사하겠습니다!!

 

 

 

 

 

 

Reference : 

https://stackoverflow.com/questions/3183841/base64-vs-hex-for-sending-binary-content-over-the-internet-in-xml-doc

http://fileformats.archiveteam.org/wiki/Hex_encoding

https://chrisrng.svbtle.com/url-encoding

https://www.raywenderlich.com/books/swift-apprentice/v6.0/chapters/22-encoding-decoding-types

https://www.javatpoint.com/types-of-encoding-techniques

https://namu.wiki/w/%EC%9D%B8%EC%BD%94%EB%94%A9 

반응형

댓글