비트와 바이트, 진수 표현법

비트와 바이트

비전공자이기 때문에 컴퓨터 공학 관련 기초는 없었고, 실제 앱을 만드는 과정에서도 비트 단위를 다루는 일은 없었기에 안심(?)하고 있었는데, 새로 맡은 프로젝트가 암호화폐 지갑 앱이라 암호에 대해 공부하다보니 비트 단위 처리를 안 할 수 없었다. 결국 비트와 바이트에 대한 얕은 이해라도 필요했다.

비트

우선 컴퓨터는 0과 1만을 알아들을 수 있다. 그 이유는 컴퓨터는 전원을 이용한 기계이기 때문에 꺼짐(0) 켜짐(1)로 모든 정보를 표현하기 때문이다. 비트는 0과 1 두 가지 상태만 저장할 수 있기 때문에 1비트는 2개의 상태만을 저장할 수 있다. (0 or 1) 그렇다면 2비트는? 4개 (00 or 01 or 10 or 11) 흔히 비트로 표현할 수 있는 상태의 수는 2의 n제곱으로 표현한다.

바이트

바이트는 1비트가 8개가 모여 구성된다. 비트가 8개 모였기 때문에 2*2*2*2*2*2*2*2 인 256개의 상태를 표현할 수 있다. (숫자 0 ~ 255) 1바이트는 1캐릭터라고도 불리는데 그 이유는 영어, 숫자, 기타 기호들이 각 글자당 1바이트를 차지하기 때문이다. 한글은 utf-8(Unicode) 환경에서는 3바이트를 차지하고, ASCII(ANSI) 환경에서는 2바이트를 차지한다.

2진수

컴퓨터는 0과 1만 알아들을 수 있다고 했는데, 2진법으로 어떻게 데이터를 표현할까? 10진수를 쓰는 일반적인 상황에서는 0부터 9까지의 숫자를 쓰기 때문에 9에 1을 더하면 10이 된다. 이 표현방법을 적용하면 이해하기 쉽다.

0 -> 0 | 1 -> 1 | 2 -> 10 | 3 -> 11 | 4 -> 100 | 5 -> 101 ...

2진수를 10진수로 표현하는 방법은 표를 만들어 1이 있는 자리의 수를 곱하고, 그 수들을 더하면 된다.

// 2진수 1011이 있다면...

...256 128 64 32 16 8 4 2 1 // 이런 표를 그려두고
                    1 0 1 1 // 이렇게 2진수를 자리수에 맞춰 넣어둔 후 계산을 하면 된다.

(8*1) + (4*0) + (2*1) + (1*1) = 11  된다.

반대로 10진수를 2진수로 표현하는 방법은 그냥 2진수로 계속 나누면 된다.

2 / 11 = 5 ...나머지 1
2 / 5 = 2 ...나머지 1
2 / 2 = 1 ...나머지 0
2 / 1 = 0 ...나머지 1

// 나머지 수를 아래서부터 위로 정렬하면 1011이 된다. 끝~

16진수

2진수는 0과 1로만 표현한다면, 16진수는 0~9, 그리고 A~F까지로 표현한다.

0 -> 0 | 1 -> 1 | 2 -> 2 | ... | 9 -> 9 | 10 -> A | 11 -> B | ... | 15 -> F | 16 -> 10 ...

16진수를 쓰는 경우 0x를 앞에 붙여 16진수임을 알리는 경우가 많다. 그렇다면 16진수로 10진수를 표현하는 방법은 어떻게 될까?

// 16진수 0x1F가 있다면
...4096 256 16 1 // 이런 표를 그려두고
             1 f // 이렇게 16진수를 자리수에 맞춰 넣어둔 후 계산을 하면 된다.
(16*1) + (1*F) = 31 된다. // (F는 15이기 때문에)

반대로 10진수를 16진수로 표현하는 방법은 10진수 -> 2진수처럼 계속 16으로 나누면 된다.

16 / 31 = 1 ...나머지 15
16 / 1 = 0 ...나머지 16

// 나머지 수를 아래서부터 위로 정렬하면 0x1F가 된다. (15는 F이기 때문)

자, 비트와 바이트는 알겠다. 근데 2진법 16진법 같은건 왜 필요한건데? 아까 말했듯 컴퓨터는 0과 1밖에 모른다. 16진법을 쓰는 이유는 그저 사람이 편하기 위해서다. 16진수의 자릿수 하나가 2*2*2*2 가지를 표현할 수 있기 때문에 16진수 2자릿수를 쓰면 2*2*2*2*2*2*2*2 즉 256 가지를 표현할 수 있고 이는 1바이트다. 즉 1바이트를 16진수 두 자리를 통해 표현할 수 있다는 것이다. 1바이트는 8비트이며, 이 8비트의 2진수(255)는 1111 1111로 표현할 수 있는데, 이를 16진수로 표현하면 0xFF 로 끝난다.