# 엔디안(Endian) 데이터의 바이트 순서, 즉 엔디안(Endian)은 컴퓨터 과학에서 중요한 개념 중 하나이다. 엔디안은 다중 바이트 데이터가 메모리에 저장되거나 전송될 때, 바이트의 순서를 정의한다. 주로 16비트, 32비트, 64비트 등 다중 바이트로 구성된 데이터 타입에서 바이트 순서가 중요하게 고려된다. 엔디안에는 크게 빅 엔디안(Big Endian)과 리틀 엔디안(Little Endian) 두 가지 방식이 있다. 이 두 방식은 데이터를 메모리에 저장하거나 전송할 때 바이트의 순서를 정의한다. ## 빅 엔디안(Big Endian) ![Big Endian](https://hackmd.io/_uploads/H1cqVOUy0.png) 빅 엔디안은 가장 큰 단위의 바이트가 가장 낮은 메모리 주소에 저장되는 방식이다. 예를 들어 `0x0A0B0C0D`와 같은 4바이트 정수가 있을 때, 빅 엔디안 방식에서는 0A가 가장 낮은 주소에, 0D가 가장 높은 주소에 배치된다. ### 빅 엔디안의 특징 - 네트워크 프로토콜에서 주로 사용된다. (TCP/IP가 대표적 예) - 가독성이 높다. (인간이 읽기 쉬운 순서로 데이터를 해석할 수 있다) ## 리틀 엔디안(Little Endian) ![Little Endian](https://hackmd.io/_uploads/ByBiNuIJA.png) 리틀 엔디안은 가장 작은 단위의 바이트가 가장 낮은 메모리 주소에 저장되는 방식이다. 예를 들어 `0x0A0B0C0D`와 같은 4바이트 정수가 있을 때, 리틀 엔디안 방식에서는 0D가 가장 낮은 주소에, 0A가 가장 높은 주소에 배치된다. ### 리틀 엔디안의 특징 - 개인 컴퓨터의 CPU에서 주로 사용된다. (Intel x86 아키텍처가 대표적 예) - 데이터를 처리할 때 변환 과정이 더 간단하다. ## Little Endian vs Big Endian | 빅 엔디안 (Big Endian) | 리틀 엔디안 (Little Endian) | | ------------------------------------------------------- | ---------------------------------------------------------- | | ![Big Endian](https://hackmd.io/_uploads/H1cqVOUy0.png) | ![Little Endian](https://hackmd.io/_uploads/ByBiNuIJA.png) | | 가장 큰 단위의 바이트가 가장 낮은 메모리 주소에 저장 | 가장 작은 단위의 바이트가 가장 낮은 메모리 주소에 저장 | | 네트워크 프로토콜에서 주로 사용 | 개인 컴퓨터의 CPU에서 주로 사용 | | 가독성이 높음 | 데이터 처리가 간단함 | ## 엔디안의 중요성 엔디안은 데이터를 저장하고 전송하는 방식을 정의한다. 따라서 데이터를 저장하거나 전송할 때 엔디안을 고려하지 않으면 데이터를 잘못 해석할 수 있다. 예를 들어, 빅 엔디안 방식으로 저장된 데이터를 리틀 엔디안 방식으로 해석하면 데이터가 왜곡되어 나타날 수 있다. 따라서 데이터를 저장하거나 전송할 때 엔디안을 고려하여 데이터를 올바르게 해석할 수 있도록 해야 한다. 그래서 네트워크 프로토콜이나 파일 포맷 등에서 데이터를 저장하거나 전송할 때 엔디안을 명시적으로 지정하는 경우가 많다. ## Java에서의 엔디안 처리 Java에서는 기본적으로 빅 엔디안 방식을 사용한다. 하지만 ByteBuffer 클래스를 사용하면 빅 엔디안과 리틀 엔디안 방식으로 데이터를 읽고 쓸 수 있다. ### ByteBuffer를 사용한 예제 Java에서 ByteBuffer 클래스를 사용하여 빅 엔디안과 리틀 엔디안 방식으로 정수를 읽고 쓰는 방법을 살펴보자. ```java import java.nio.ByteBuffer; public class EndianExample { public static void main(String[] args) { int value = 0x0A0B0C0D; // 빅 엔디안으로 ByteBuffer 생성 ByteBuffer bbBig = ByteBuffer.allocate(4); bbBig.putInt(value); System.out.println("빅 엔디안: "); for (byte b : bbBig.array()) { System.out.format("0x%02X ", b); } // 리틀 엔디안으로 ByteBuffer 생성 ByteBuffer bbLittle = ByteBuffer.allocate(4).order(java.nio.ByteOrder.LITTLE_ENDIAN); bbLittle.putInt(value); System.out.println("\n리틀 엔디안: "); for (byte b : bbLittle.array()) { System.out.format("0x%02X ", b); } } } ``` - 위의 코드는 4바이트 정수 `0x0A0B0C0D`를 빅 엔디안과 리틀 엔디안 방식으로 읽고 쓰는 예제이다. - 빅 엔디안의 경우 `0A 0B 0C 0D`와 같이 출력되고, 리틀 엔디안의 경우 `0D 0C 0B 0A`와 같이 출력된다. > - Q: 자바의 직렬화에서 기본적으로 어떤 엔디안을 사용할까? > - A: 자바는 기본적으로 빅 엔디안 방식을 사용한다. 따라서 자바의 직렬화된 데이터도 빅 엔디안 방식으로 저장된다.