진법 변환 가이드: 2진법, 16진법, 8진법 완벽 해설
#1A2B3C 같은 16진법 색상 코드나 chmod 755 같은 Unix 권한 설정을 보면서 이 숫자들이 어디서 나온 건지 궁금했던 적이 있다면, 당신만 그런 것이 아닙니다. 진법은 대부분의 개발자가 매일 아무 생각 없이 사용하는 기초 개념 중 하나입니다 — 막상 진법 간 변환이 필요한 순간이 올 때까지는 말이죠.
이제 확실히 정리해 봅시다. 이 가이드에서는 프로그래밍에서 중요한 숫자 체계들과 진법 간 변환 방법, 그리고 각 진법이 실제로 어디에 쓰이는지 살펴봅니다.
"진법"이 정확히 무슨 뜻인가요?
우리가 10진법(십진법)을 사용하는 이유는 손가락이 열 개이기 때문입니다. 각 자릿수는 10의 거듭제곱을 나타냅니다:
4 2 7
| | |
| | └── 7 × 10⁰ = 7
| └────── 2 × 10¹ = 20
└────────── 4 × 10² = 400
───
Total = 427
이것이 자릿값 표기법입니다. "진법"(기수라고도 함)은 해당 체계에서 사용할 수 있는 고유한 숫자의 개수와 각 자릿수에 곱해지는 값을 알려줍니다. 10진법은 0–9의 숫자를 사용하고, 2진법은 0–1, 16진법은 0–9와 A–F를 사용합니다.
모든 진법에서 개념은 동일합니다 — 사용 가능한 기호의 수와 자릿수별 승수만 달라질 뿐입니다.
재미있는 사실: 바빌로니아인들은 60진법을 사용했습니다. 그래서 1분이 60초이고, 원이 360도인 것입니다.
2진법(Base-2): 하드웨어의 언어
컴퓨터가 2진법을 사용하는 이유
컴퓨터는 트랜지스터로 작동하며, 트랜지스터에는 켜짐(on)과 꺼짐(off) 두 가지 안정적인 상태가 있습니다. 이것이 1과 0에 완벽하게 대응됩니다. 이론적으로 3진법 컴퓨터를 만들 수도 있겠지만, 세 가지 전압 수준을 구분하는 것은 두 가지를 구분하는 것보다 훨씬 어렵고 오류가 발생하기 쉽습니다. 2진법이 선택된 이유는 단순하고 안정적이기 때문입니다.
2진수 읽는 법
2진법도 10진법과 같은 원리로 작동하지만, 각 자릿수가 2의 거듭제곱을 나타냅니다:
1 0 1 1 0 1
| | | | | |
| | | | | └── 1 × 2⁰ = 1
| | | | └────── 0 × 2¹ = 0
| | | └────────── 1 × 2² = 4
| | └────────────── 1 × 2³ = 8
| └────────────────── 0 × 2⁴ = 0
└────────────────────── 1 × 2⁵ = 32
──
Total = 45
따라서 2진법의 101101은 10진법의 45입니다. 오른쪽에서 왼쪽으로 읽으면서 자릿값이 매번 두 배로 늘어납니다: 1, 2, 4, 8, 16, 32, 64, 128...
비트, 니블, 바이트
- 비트(Bit): 하나의 2진 숫자 (0 또는 1)
- 니블(Nibble): 4비트 (16진수 한 자리에 해당, 값 0–15)
- 바이트(Byte): 8비트 (값 0–255)
- 킬로바이트(Kilobyte): 1,024바이트 (2¹⁰)
하나의 바이트로 256가지 서로 다른 값을 표현할 수 있습니다. 그래서 ASCII 문자가 1바이트에 들어가고, RGB 색상 채널이 0에서 255까지인 것입니다.
2진법 산술의 기초
2진법 덧셈은 10진법과 같은 규칙을 따르지만, 10이 아닌 2에서 올림이 발생합니다:
1 0 1 1 (11 in decimal)
+ 0 1 1 0 ( 6 in decimal)
─────────
1 0 0 0 1 (17 in decimal)
2진법에서 1 + 1 = 10이 됩니다 (10진법에서 9 + 1 = 10이 되는 것과 같은 원리). 0을 쓰고 1을 올립니다.
8진법(Base-8): 레거시 시스템
간략한 역사
8진법은 1960~70년대에 PDP-8 같은 컴퓨터에서 널리 사용되었습니다. 이 컴퓨터는 12비트 워드를 사용했는데, 이를 3비트씩 네 그룹으로 깔끔하게 나눌 수 있었습니다. 8진수 한 자리가 정확히 3개의 2진 숫자에 대응하므로, 편리한 약식 표기법이 되었습니다.
8진법이 아직 쓰이는 곳
오늘날 가장 흔히 볼 수 있는 곳은 Unix 파일 권한입니다. chmod 755 script.sh를 입력할 때, 각 숫자는 읽기(4), 쓰기(2), 실행(1) 권한을 나타내는 8진수입니다:
7 = 4 + 2 + 1 = rwx (owner: read, write, execute)
5 = 4 + 0 + 1 = r-x (group: read, execute)
5 = 4 + 0 + 1 = r-x (others: read, execute)
프로그래밍에서 8진수는 0o 접두사를 사용합니다 (C에서는 앞에 0만 붙이는데, 이것 때문에 버그가 수없이 발생했습니다):
const permissions = 0o755; // 493 in decimal
console.log(permissions.toString(8)); // "755"
JavaScript와 Python에서 주의하세요: 0755처럼 앞에 0을 붙이면 일부 문맥에서 8진수로 해석될 수 있습니다. 모호함을 피하려면 항상 0o 접두사를 명시적으로 사용하세요.
16진법(Base-16): 개발자의 최애 진법
16진법이 존재하는 이유
16진법은 현실적인 문제를 해결합니다: 2진수는 금방 길어진다는 것입니다. 10진수 255는 2진법으로 11111111 — 무려 여덟 자리입니다. 16진법으로는 FF 두 자리면 끝납니다. 16진수 한 자리가 정확히 4개의 2진 숫자(니블)에 대응하므로, 변환이 매우 쉽고 숫자도 간결하게 유지됩니다.
16진법은 0–9의 숫자와 A–F의 문자를 사용합니다:
| Decimal | Binary | Hex |
|---|---|---|
| 0 | 0000 | 0 |
| 1 | 0001 | 1 |
| 9 | 1001 | 9 |
| 10 | 1010 | A |
| 11 | 1011 | B |
| 15 | 1111 | F |
실전에서 만나는 16진법
웹 색상은 16진법의 가장 대표적인 활용 사례입니다. #FF5733을 분해하면:
#FF5733
││││││
││││└┘── Blue: 0x33 = 51
││└┘──── Green: 0x57 = 87
└┘────── Red: 0xFF = 255
메모리 주소는 디버거에서 16진법으로 표시됩니다: 0x7FFF5FBFFA10은 10진법 값 140,734,799,804,944보다 훨씬 읽기 쉽습니다.
MAC 주소는 콜론으로 구분된 16진수 쌍을 사용합니다: A4:83:E7:2B:00:1F.
CSS 색상: rgba(255, 87, 51, 1.0)과 #FF5733은 같은 색을 나타냅니다 — 16진법이 더 간결할 뿐입니다.
진법 간 변환
10진법 → 2진법
2로 반복해서 나누고 나머지를 아래에서 위로 읽습니다:
45 ÷ 2 = 22 remainder 1 ↑
22 ÷ 2 = 11 remainder 0 │
11 ÷ 2 = 5 remainder 1 │ Read upward:
5 ÷ 2 = 2 remainder 1 │ 101101
2 ÷ 2 = 1 remainder 0 │
1 ÷ 2 = 0 remainder 1 │
결과: 10진법 45 = 2진법 101101.
10진법 → 16진법
같은 방법이지만 16으로 나눕니다:
427 ÷ 16 = 26 remainder 11 (B) ↑
26 ÷ 16 = 1 remainder 10 (A) │ Read upward: 1AB
1 ÷ 16 = 0 remainder 1 │
결과: 10진법 427 = 16진법 1AB.
2진법 → 16진법 (가장 쉬운 변환)
2진 숫자를 오른쪽부터 4개씩 묶고, 각 그룹을 변환합니다:
Binary: 10 1101
Padded: 0010 1101
Groups: 2 D
Result: 0x2D
검증: 0x2D = 2×16 + 13 = 45 ✓
16진법과 2진법이 천생연분인 이유가 바로 이것입니다 — 변환이 기계적으로 이루어집니다.
16진법 → 2진법
역순으로 진행합니다. 각 16진수 자리를 4자리 2진수로 확장합니다:
Hex: F A 3
Binary: 1111 1010 0011
Result: 111110100011
팁: 0–F의 2진법 패턴을 외워두세요 (16개뿐입니다). 이것만 알면 16진법↔2진법 변환을 머릿속에서 즉시 할 수 있습니다. 2의 거듭제곱부터 시작하세요: 1=0001, 2=0010, 4=0100, 8=1000.
프로그래밍 언어별 진법 표기법
모든 주요 프로그래밍 언어에는 다양한 진법으로 숫자를 쓸 수 있는 문법이 있습니다:
// JavaScript
const binary = 0b101101; // 45
const octal = 0o55; // 45
const hex = 0x2D; // 45
const decimal = 45; // 45
// Convert to string in any base
(45).toString(2); // "101101"
(45).toString(8); // "55"
(45).toString(16); // "2d"
// Parse from string
parseInt("101101", 2); // 45
parseInt("55", 8); // 45
parseInt("2D", 16); // 45
# Python
binary = 0b101101 # 45
octal = 0o55 # 45
hexval = 0x2D # 45
# Convert to string
bin(45) # '0b101101'
oct(45) # '0o55'
hex(45) # '0x2d'
# Parse from string
int("101101", 2) # 45
int("55", 8) # 45
int("2D", 16) # 45
// C / C++
int binary = 0b101101; // 45 (C23 / GCC extension)
int octal = 055; // 45 (leading zero = octal!)
int hex = 0x2D; // 45
C의 함정을 주목하세요: 앞에 0이 붙으면 8진수를 의미합니다. int x = 010;이라고 쓰면 10이 아닌 8이 됩니다. 이것 때문에 수많은 프로그래머가 함정에 빠졌습니다.
실전 활용 사례
비트 연산과 플래그
16진법은 비트마스크의 표준입니다. 한 자리가 정확히 4개의 플래그를 다루기 때문입니다:
const READ = 0x01; // 0001
const WRITE = 0x02; // 0010
const EXECUTE = 0x04; // 0100
const ADMIN = 0x08; // 1000
let permissions = READ | WRITE; // 0x03 = 0011
if (permissions & EXECUTE) {
// check if execute bit is set
}
디버깅과 메모리 검사
세그폴트 주소 0xDEADBEEF나 메모리 초기화 값 0xCAFEBABE를 본 적이 있다면, 이것들은 메모리 덤프에서 쉽게 눈에 띄도록 의도적으로 선택된 16진수 상수입니다. Java 클래스 파일은 매직 넘버 0xCAFEBABE로 시작합니다 — 네, 누군가 이름 짓는 걸 즐겼던 겁니다.
네트워크 프로토콜
IPv6 주소는 16진법 표기를 사용합니다: 2001:0db8:85a3:0000:0000:8a2e:0370:7334. MAC 주소, USB 벤더 ID, Bluetooth UUID 모두 16진법 표현을 사용합니다. 2진 데이터를 간결하면서도 읽기 쉽게 유지할 수 있기 때문입니다.
직접 해보세요
수작업 계산은 건너뛰세요. 저희 진법 변환기는 10진법, 2진법, 8진법, 16진법, 또는 36진법까지 모든 진법 간 변환을 즉시 처리합니다. 숫자를 붙여넣고, 원본 진법과 대상 진법을 선택하면 바로 결과를 확인할 수 있습니다. 모든 처리는 브라우저에서 이루어지므로, 서버로 전송되는 데이터는 없습니다.
특히 다음과 같은 경우에 유용합니다:
- 16진법 메모리 덤프를 10진법으로 변환하여 디버깅할 때
- Unix 권한을 2진법/8진법으로 계산할 때
- 16진법과 RGB 값 사이의 색상 코드를 확인할 때
- 2의 거듭제곱이 아닌 진법 간 변환이 필요할 때
관련 자료
- Base64 인코딩 해설 — Base64는 바이너리를 텍스트로 인코딩하기 위해 다른 접근 방식(6비트 그룹을 64개 문자에 매핑)을 사용합니다
- 해시 알고리즘 비교 — 해시 출력은 일반적으로 16진법으로 표시됩니다
- 진법 변환기 — 브라우저에서 모든 진법 간 변환을 즉시 수행하세요
🛠️ 지금 바로 사용해보세요: 진법 변환기 — 2진법, 8진법, 10진법, 16진법, 그리고 36진법까지 모든 진법 간 변환. 100% 클라이언트 사이드, 완전 무료.