들어가며
누군가 홈페이지에서 "뛣뷁꿇꼶꺎...."와 같은 이상한 문자가 나오는 것은 왜 그런 것인가 저에게 물었던 적이 있습니다. 개발을 하면서 아주 간단한 부분조차 제대로 설명할 수 없다는 것을 깨달을 때가 있습니다. 항상 대충 알고만 넘어갔던 부분들을 이제는 제대로 알아야겠다고 생각했습니다. 지금부터 비트와 바이트, 그리고 문자 인코딩에 대해 알아보겠습니다.
비트와 바이트
컴퓨터가 이해할 수 있는 최소의 정보 단위는 0과 1밖에 없습니다. 컴퓨터는 0과 1의 조합으로 이루어진 정보들을 처리할 수 있습니다. 컴퓨터가 처리할 수 있는 가장 작은 단위의 정보를 나타내는 것이 bit입니다. 비트는 0 또는 1이라는 정보를 담을 수 있습니다. 그리고 이런 2진수(Binary Digit)들이 모여서 조금 더 큰 범위의 데이터를 담을 수가 있습니다.
1비트는 0과 1. 2종류만 담을 수 있고, 2가지의 비트로는 (0, 0), (0, 1), (1, 0), (1, 1) 총 4가지를 담을 수 있습니다. 경우의 수 공식을 이용하면, 한 비트당 2가지의 경우를 나타내므로 2x2는 4. 즉 총 네 가지의 경우로 나타낼 수 있습니다. 3비트로는 2x2x2의 경우 8가지의 경우를 나타낼 수 있습니다.
컴퓨터에서 데이터를 처리할 때 가장 기본적인 단위를 1 바이트라고 이야기하는데, 1바이트는 8비트로 구성되어있습니다. 256가지의 다른 수를 담을 수 있으므로 숫자 0부터 시작한다면 255까지의 정보를 나타낼 수 있습니다.
그렇다면, 비트와 바이트의 용량은 어떻게 표기할 수 있을까요? 이에 대해 알아보겠습니다.
Mega Mebi
만약 1바이트에서 1024를 곱해본다고 가정해보겠습니다. 1바이트에서 1024를 곱한 것이 1KB입니다. 1KB에 1024를 곱한 것이 1MB가 됩니다. 동일하게 1024를 곱하면 1GB가 되며 여기에 1024를 곱하면 1TB가 됩니다. 이 부분은 운영체제에서 사이즈를 확인할 때 주로 볼 수 있습니다.
하지만 2진수는 컴퓨터를 사용하는 사용자들에게 익숙하지 않으니, 사용자들에게 조금 더 익숙한 10진수 단위로 곱해진 단위로 환산해보겠습니다. 만약 1바이트에 1000을 곱하면 1KB가 되고, 여기에 1000을 곱해서 1MB가 됩니다. 이런 사이즈들은 외장 디스크나 USB에 표시됩니다. 예전에는 컴퓨터의 용량이 적었기 때문에, 차이가 큰 문제점은 아니었습니다. 1000바이트와 1024 바이트는 큰 차이가 없을 수 있지만, 테라바이트를 이야기한다면, 1000GB와 1024GB에는 큰 차이가 있을 수 있습니다.
예를 들어 100MB의 USB를 사서 운영체제에 넣었더니 실제로 내가 저장할 수 있는 사이즈는 95.37MB 밖에 안 뜨는 경우가 있었습니다. 이런 혼돈을 잠재우고자 IEC에서 다른 표기법을 제안합니다. KB와 MB는 사람들이 쓰던 10진수 단위로 남겨두고 바이너리 형태로 이야기할 땐 Kibibyte, mebibyte, gibibyte, tebibyte라고 이야기하자 약속을 하게 됩니다.
지금까지 0과 1을 얼마나 저장할 수 있는가에 대해 알아봤다면, 지금부터는 어떻게 하면 문자를 2진수로 나타낼 수 있을까? 에 대해 알아보겠습니다. 이를 위해 나타난 것이 바로 ASCII입니다.
ASCII와 Unicode
ASCII에서 알파벳 A는 1000001로 표기가 되며, 알파벳 N은 1001110으로 표기가 됩니다. 이것들은 사람들이 미리 약속해둔 테이블을 이용해서 서로 변환할 수 있습니다. 위의 ASCII 문자열 표를 활용해서 간단한 문자를 이진수로 나타낼 수 있습니다.
아스키코드에 들어있는 문자열은 1바이트로 모든 문자열을 표기할 수 있습니다. 하지만 아스키코드의 한계점이 존재합니다. 이 세상에는 정말 다양한 문자들이 있습니다. 하지만 아스키코드에는 모든 문자열이 들어있지 않습니다. 한국어도 여기에 포함되지 않습니다. 이를 위해 나온 것이 바로 유니코드입니다.
우리 지구 상에서 만날 수 있는 다양한 문자들을 포함하는 것이 유니코드입니다. 유니코드에 들어있는 문자열은 1바이트에 다 담을 수 없기 때문에 2바이트 또는 그 이상의 바이트를 이용해서 전체적인 문자열을 나타낼 수 있습니다. 유니코드에서는 아스키코드에 있는 문자열뿐 아니라 다양한 언어의 문자열을 포함하고 있습니다. 우리가 사용하는 심벌과 이모지 같은 것들도 포함되어 있고, 한글도 포함되어 있습니다. 이처럼 유니코드는 다양한 문자열들을 갖고 있습니다.
정리하자면 컴퓨터는 0과 1을 담는 비트라는 최소 단위를 갖고 있고, 비트를 여러 개 묶어서 더 많은 데이터를 저장할 수 있습니다. 컴퓨터 프로그래밍에서는 1바이트를 가장 최소의 단위로 잡고 보는데, 프로그래밍에서 변수를 선언할 때, 어떤 데이터 타입이냐에 따라 메모리에 얼마나 크게 공간이 확보되는지가 정해집니다. 임베디드나 메모리가 넉넉하지 못한 환경에서 동작하는 프로그램 같은 경우엔 데이터 타입을 알맞게 선택해서 효율적으로 작성하는 것이 중요합니다.
그렇다면, 우리가 어떻게 현존하는 많은 문자열들을 컴퓨터가 이해할 수 있게 인코딩할 수 있을까요? 그 규격을 약속하는 것이 Text Encoding입니다
Text Encoding
예전에는 각 나라별로, 언어마다 다양한 텍스트 인코딩이 존재했습니다. 그러다 보니 자국 언어에 맞는 인코딩 방식을 택하다 보니, 다른 언어를 쓰는 국가에서 홈페이지를 불러올 때, 언어를 이해할 수 없어서, 서로 다른 인코딩 규격 때문에 웹사이트가 깨지거나 한글문서가 읽어지지 않는 문제점들이 많이 발생했습니다. 이것을 해결하기 위해 나온 것이 UTF-8이라는 인코딩 방식입니다. unicode transformation for mat(8-bit)의 약자입니다. mat은 8비트를 말합니다. 즉, UTF-8은 유니코드를 인코딩하는 방식을 말합니다.
UTF-8은 기존 아스키뿐 아니라 모든 유니코드를 나타낼 수 있는 웹사이트에서 기본적으로 사용되고 있고 통상적으로 사용되고 있는 텍스트 인코딩입니다. UTF-8은 가변 길이 유니코드 인코딩 방식입니다. 즉 길이가 정해져 있지 않고 필요에 의해 길어질 수 있는 것을 말합니다. 모든 아스키코드는 7비트로 나타낼 수 있기 때문에 UTF-8에서는 1바이트로 다 표현할 수 있고, 유니코드의 경우 최소 2바이트부터 4바이트 까지 표현할 수 있습니다. 이처럼 UTF-8에서는 1바이트로 표현할 수 있다면 그대로 표현하고, 만약 2바이트 이상이 필요하다면 첫 번째 덩어리에서 10을 앞에다 붙여주고, 두 번째는 110을 붙여주면서 총문자를 나타내는데 몇 바이트가 필요한지 힌트를 줄 수 있습니다. 이처럼 UTF-8은 가변 길이이기 때문에 바이트가 더 필요하다면 데이터의 범위를 더 늘려서 더 많은 문자열을 나타낼 수 있고, UTF-16이라는 인코딩 방식이 있지만 이것도 가변 길이 이긴 하지만 기본적으로 2바이트를 사용하기 때문에 아스키와 같이 1바이트로만 충분히 표현할 수 있음에도 2바이트를 소모하게 됩니다. 그래서 UTF-8이 통상적으로 많이 이용됩니다.
마치며
공부를 하며 그동안 아주 기초적인 것들을 제대로 공부하지 않았다는 것을 깨닫습니다. 좋은 기술을 배우는 것도 좋지만, 기술의 기반이 되는 기초적인 지식을 먼저 쌓는 것이 중요하다는 것을 다시금 깨달았습니다. 기초가 튼튼한 개발자가 되고 싶습니다.
출처
'Web' 카테고리의 다른 글
[Web] 다중 서버에서 세션을 관리해보자 - 2 (feat 세션 불일치) (0) | 2022.01.05 |
---|---|
[Web] 다중 서버에서 세션을 관리해보자 - 1 (feat Scale-up, Scale-out) (0) | 2021.12.29 |
[Web] 세션을 알아보자 (0) | 2021.12.23 |
[Web] 로컬 스토리지와 세션 스토리지 (0) | 2021.12.11 |
[Web] 쿠키를 알아보자 (0) | 2021.12.11 |