Hex to ASCII와 역변환: 개발자를 위한 실용적인 Hex 인코딩 가이드
Source: Dev.to
(번역을 진행하려면 번역할 텍스트를 제공해 주시겠어요?)
16진수 기본
16진수(베이스‑16)는 기호 0‑9와 A‑F를 사용합니다.
각 16진수 자리수는 4비트를 나타내며, 두 자리 16진수는 1바이트(8비트)를 나타냅니다.
| 십진수 | 16진수 | 이진수 |
|---|---|---|
| 0 | 0 | 0000 |
| 1 | 1 | 0001 |
| … | … | … |
| 9 | 9 | 1001 |
| 10 | A | 1010 |
| 11 | B | 1011 |
| 12 | C | 1100 |
| 13 | D | 1101 |
| 14 | E | 1110 |
| 15 | F | 1111 |
왜 베이스‑16인가? 컴퓨터는 이진수로 동작하고, 16진수는 이진수와 완벽히 매핑됩니다 — 4비트마다 1개의 16진수 자리수가 됩니다. 이는 이진 데이터를 가장 사람이 읽기 쉬운 형태로 표현하는 방법입니다.
ASCII는 각 문자에 번호(0‑127)를 할당합니다. 16진수를 ASCII로 변환한다는 것은 그 번호들을 다시 문자로 변환하는 것을 의미합니다.
Source: …
헥스를 ASCII로 변환하고 다시 변환하기
예시 변환
| Hex | Decimal | ASCII |
|---|---|---|
| 48 | 72 | H |
| 65 | 101 | e |
| 6C | 108 | l |
| 6C | 108 | l |
| 6F | 111 | o |
결과: Hello 👋
다른 방향으로 변환하는 것도 마찬가지로 간단합니다:
"Dev" → D(44) e(65) v(76) → 44 65 76
JavaScript
// Hex → ASCII
function hexToAscii(hex) {
return hex
.match(/.{1,2}/g)
.map(byte => String.fromCharCode(parseInt(byte, 16)))
.join('');
}
// ASCII → Hex
function asciiToHex(str) {
return Array.from(str)
.map(char => char.charCodeAt(0).toString(16).padStart(2, '0'))
.join(' ');
}
console.log(hexToAscii('48656C6C6F')); // "Hello"
console.log(asciiToHex('Hello')); // "48 65 6c 6c 6f"
Python
# Hex → ASCII
def hex_to_ascii(hex_string):
return bytes.fromhex(hex_string).decode('ascii')
# ASCII → Hex
def ascii_to_hex(text):
return ' '.join(f'{ord(c):02x}' for c in text)
print(hex_to_ascii('48656C6C6F')) # "Hello"
print(ascii_to_hex('Hello')) # "48 65 6c 6c 6f"
Bash (using xxd and od)
# Hex → ASCII
echo '48656C6C6F' | xxd -r -p
# Output: Hello
# ASCII → Hex (continuous)
echo -n 'Hello' | xxd -p
# Output: 48656c6c6f
# ASCII → Hex (pretty, space‑separated)
echo -n 'Hello' | od -A n -t x1
# Output: 48 65 6c 6c 6f
실용적인 적용
-
패킷 캡처 (Wireshark, tcpdump)는 페이로드를 16진수로 표시합니다. 덤프에서 ASCII 텍스트를 찾는 것은 기본적인 디버깅 기술입니다:
0000 47 45 54 20 2f 61 70 69 GET /api 0008 2f 75 73 65 72 73 20 48 /users H 0010 54 54 50 2f 31 2e 31 TTP/1.1 -
웹 색상은 16진수 값입니다:
color: #FF5733; /* R:255 G:87 B:51 */ background: #2D2D2D; /* Dark gray */ -
UTF‑8 인코딩 예시:
문자 UTF‑8 16진수 é C3 A9 € E2 82 AC 🔥 F0 9F 94 A5 -
파일 시그니처 (매직 넘버):
포맷 16진수 시그니처 PNG 89 50 4E 47 0D 0A 1A 0A JPEG FF D8 FF PDF 25 50 44 46 ( %PDF)GIF 47 49 46 38 ( GIF8) -
메모리 주소 (예: 크래시 덤프에서):
Segfault at address 0x7FFE4B2A1000 Stack pointer: 0x00007FFEEFBFF5A0
공통 16진수 형식
| 형식 | 예시 | 일반적인 사용 |
|---|---|---|
| Space‑separated | 48 65 6C 6C 6F | 헥스 덤프, 디버거 |
| No separator | 48656C6C6F | URL, 해시 |
0x prefix | 0x48, 0x65 | C/C++, 메모리 리터럴 |
\x escape | \x48\x65 | Python, 문자열 리터럴 |
% prefix | %48%65 | URL 인코딩 |
ASCII vs. 확장/유니코드
| 인코딩 | 문자 | Hex 바이트 |
|---|---|---|
| ASCII | A | 41 |
| UTF‑8 | ñ | C3 B1 |
| UTF‑8 | 漢 | E6 BC A2 |
| UTF‑8 | 🚀 | F0 9F 9A 80 |
ASCII는 0‑127(7비트)만 포함합니다. 128‑255 값은 “확장 ASCII”(코드 페이지에 따라 다름)에 해당합니다. 현대 텍스트는 유니코드를 사용하며, 위와 같이 UTF‑8로 인코딩됩니다.
전문가 팁
소문자는 0x61에서 시작하고, 대문자는 0x41에서 시작합니다. 차이는 항상 0x20 (32)입니다. 따라서 대소문자를 전환하는 것은 단순히 한 비트를 뒤집는 것과 같습니다.
Handy Tool
빠르고, 가입이나 추적 없이 브라우저 내에서 변환하려면 hextoascii.co 를 사용해 보세요 – 헥스를 붙여넣고 ASCII를 얻으세요 (그 반대도 가능합니다).
Conclusion
헥스 인코딩은 네트워크 디버깅, 바이너리 분석, 색상 코드, 인코딩 문제 등에서 다시 등장하는 기본적인 기술입니다. 변환 과정을 내면화하면, 생각하지 않아도 헥스 덤프에서 패턴을 인식하게 됩니다.
당신이 겪었던 가장 이상한 헥스‑디버깅 상황은 무엇인가요? 댓글로 공유해 주세요!