# 엔디안(Endian)
데이터의 바이트 순서, 즉 엔디안(Endian)은 컴퓨터 과학에서 중요한 개념 중 하나이다.
엔디안은 다중 바이트 데이터가 메모리에 저장되거나 전송될 때, 바이트의 순서를 정의한다. 주로 16비트, 32비트, 64비트 등 다중 바이트로 구성된 데이터 타입에서 바이트 순서가 중요하게 고려된다.
엔디안에는 크게 빅 엔디안(Big Endian)과 리틀 엔디안(Little Endian) 두 가지 방식이 있다. 이 두 방식은 데이터를 메모리에 저장하거나 전송할 때 바이트의 순서를 정의한다.
## 빅 엔디안(Big Endian)

빅 엔디안은 가장 큰 단위의 바이트가 가장 낮은 메모리 주소에 저장되는 방식이다.
예를 들어 `0x0A0B0C0D`와 같은 4바이트 정수가 있을 때, 빅 엔디안 방식에서는 0A가 가장 낮은 주소에, 0D가 가장 높은 주소에 배치된다.
### 빅 엔디안의 특징
- 네트워크 프로토콜에서 주로 사용된다. (TCP/IP가 대표적 예)
- 가독성이 높다. (인간이 읽기 쉬운 순서로 데이터를 해석할 수 있다)
## 리틀 엔디안(Little Endian)

리틀 엔디안은 가장 작은 단위의 바이트가 가장 낮은 메모리 주소에 저장되는 방식이다.
예를 들어 `0x0A0B0C0D`와 같은 4바이트 정수가 있을 때, 리틀 엔디안 방식에서는 0D가 가장 낮은 주소에, 0A가 가장 높은 주소에 배치된다.
### 리틀 엔디안의 특징
- 개인 컴퓨터의 CPU에서 주로 사용된다. (Intel x86 아키텍처가 대표적 예)
- 데이터를 처리할 때 변환 과정이 더 간단하다.
## Little Endian vs Big Endian
| 빅 엔디안 (Big Endian) | 리틀 엔디안 (Little Endian) |
| ------------------------------------------------------- | ---------------------------------------------------------- |
|  |  |
| 가장 큰 단위의 바이트가 가장 낮은 메모리 주소에 저장 | 가장 작은 단위의 바이트가 가장 낮은 메모리 주소에 저장 |
| 네트워크 프로토콜에서 주로 사용 | 개인 컴퓨터의 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: 자바는 기본적으로 빅 엔디안 방식을 사용한다. 따라서 자바의 직렬화된 데이터도 빅 엔디안 방식으로 저장된다.