(TIL) 2025-01-03
(TIL) 2025-01-03
엔디안
엔디안(Endian)은 컴퓨터 시스템에서 데이터의 바이트 순서를 정의하는 방식이다. 컴퓨터가 데이터를 처리하거나 저장할 때, 여러 바이트로 이루어진 데이터(예: 정수, 실수 등)가 어떻게 배열되고 읽혀야 하는지를 나타낸다. 엔디안은 크게 빅 엔디안(Big Endian)과 리틀 엔디안(Little Endian) 두 가지 방식으로 나뉜다.
빅 엔디안(Big Endian)
데이터의 가장 중요한 바이트(MSB, Most Significant Byte)가 가장 먼저 저장된다.
예) 숫자
0x12345678을 4바이트로 표현1
[12] [34] [56] [78]
장점
- 데이터를 사람이 읽고 이해하기 쉬움.
- 네트워크 프로토콜(예: IP 주소, TCP/UDP)에서 널리 사용.
리틀 엔디안(Little Endian)
데이터의 가장 덜 중요한 바이트(LSB, Least Significant Byte)가 가장 먼저 저장된다.
예) 숫자
0x12345678을 4바이트로 표현1
[78] [56] [34] [12]
장점
- 메모리 효율성을 극대화할 수 있음.
- x86 아키텍처 기반 시스템(대부분의 PC와 서버)에서 표준으로 사용
엔디안의 차이점이 중요한 이유
엔디안 방식은 다음과 같은 상황에서 매우 중요한 영향을 미칩니다:
- 다른 시스템 간 데이터 교환
- 빅 엔디안을 사용하는 시스템과 리틀 엔디안을 사용하는 시스템이 데이터를 주고받을 때 문제가 생길 수 있다. 이를 해결하려면 데이터 변환이 필요하다.
- 파일 형식
- 특정 파일 형식은 저장 시 특정 엔디안을 고정적으로 사용한다. 예를 들어, JPEG 파일은 빅 엔디안, BMP 파일은 리틀 엔디안을 주로 사용한다.
- 네트워크 프로그래밍
- 네트워크에서 데이터를 주고받을 때는 항상 빅 엔디안 형식(네트워크 바이트 순서)을 사용하기 때문에 이를 고려한 변환이 필요하다.
실제 사용 사례
네트워크 프로토콜
- 인터넷 표준(IPv4, IPv6, TCP/UDP 등)은 모두 빅 엔디안을 사용합니다.
파일 저장 및 처리
- WAV 파일: 리틀 엔디안 사용.
- TIFF 이미지: 빅 엔디안 또는 리틀 엔디안을 선택적으로 사용.
운영체제와 CPU
- 리틀 엔디안: Intel 및 AMD 프로세서(x86, x64).
- 빅 엔디안: IBM 메인프레임, 일부 RISC 프로세서(예: SPARC).
앤디안 변환 예제(Javascript)
ArrayBuffer와 DataView 객체를 활용하면 효율적으로 데이터를 조작할 수 있다.
32비트 정수를 리틀 엔디안 ↔ 빅 엔디안으로 변환
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
function swapEndian32(value) { // 32비트 정수의 바이트 순서 변경 return ( ((value & 0xff000000) >>> 24) | // 첫 번째 바이트 -> 네 번째 위치 ((value & 0x00ff0000) >>> 8) | // 두 번째 바이트 -> 세 번째 위치 ((value & 0x0000ff00) << 8) | // 세 번째 바이트 -> 두 번째 위치 ((value & 0x000000ff) << 24) // 네 번째 바이트 -> 첫 번째 위치 ); } // 테스트 let original = 0x12345678; let swapped = swapEndian32(original); console.log(original.toString(16)); // "12345678" console.log(swapped.toString(16)); // "78563412"
DataView를 사용한 변환
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
function toLittleEndian(value) { let buffer = new ArrayBuffer(4); // 4바이트 배열 생성 let view = new DataView(buffer); view.setUint32(0, value, true); // 리틀 엔디안(true) return Array.from(new Uint8Array(buffer)); // 바이트 배열 반환 } function toBigEndian(value) { let buffer = new ArrayBuffer(4); let view = new DataView(buffer); view.setUint32(0, value, false); // 빅 엔디안(false) return Array.from(new Uint8Array(buffer)); } // 테스트 let number = 0x12345678; console.log(toLittleEndian(number)); // [120, 86, 52, 18] console.log(toBigEndian(number)); // [18, 52, 86, 120]
파일 데이터 처리에서 활용
Uint8Array를 빅 엔디안에서 리틀 엔디안으로 바꾸는 코드
1 2 3 4 5 6 7 8
function reverseBytes(byteArray) { return byteArray.reverse(); // 배열을 뒤집음 } // 테스트 let bigEndianArray = new Uint8Array([0x12, 0x34, 0x56, 0x78]); let littleEndianArray = reverseBytes(bigEndianArray); console.log(littleEndianArray); // [120, 86, 52, 18]
정리
현대 컴퓨터 시스템에서는 대부분 리틀 엔디안을 사용한다. 그러나 네트워크 통신, 일부 임베디드 시스템, 혹은 이식성을 강조하는 애플리케이션에서는 여전히 빅 엔디안이 중요하다. 따라서 개발자들은 두 방식을 이해하고 데이터를 변환할 준비를 해야 합니다.
This post is licensed under CC BY 4.0 by the author.
