Post

(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와 서버)에서 표준으로 사용

엔디안의 차이점이 중요한 이유

엔디안 방식은 다음과 같은 상황에서 매우 중요한 영향을 미칩니다:

  1. 다른 시스템 간 데이터 교환
  • 빅 엔디안을 사용하는 시스템과 리틀 엔디안을 사용하는 시스템이 데이터를 주고받을 때 문제가 생길 수 있다. 이를 해결하려면 데이터 변환이 필요하다.
  1. 파일 형식
  • 특정 파일 형식은 저장 시 특정 엔디안을 고정적으로 사용한다. 예를 들어, JPEG 파일은 빅 엔디안, BMP 파일은 리틀 엔디안을 주로 사용한다.
  1. 네트워크 프로그래밍
  • 네트워크에서 데이터를 주고받을 때는 항상 빅 엔디안 형식(네트워크 바이트 순서)을 사용하기 때문에 이를 고려한 변환이 필요하다.

실제 사용 사례

  1. 네트워크 프로토콜

    • 인터넷 표준(IPv4, IPv6, TCP/UDP 등)은 모두 빅 엔디안을 사용합니다.
  2. 파일 저장 및 처리

    • WAV 파일: 리틀 엔디안 사용.
    • TIFF 이미지: 빅 엔디안 또는 리틀 엔디안을 선택적으로 사용.
  3. 운영체제와 CPU

    • 리틀 엔디안: Intel 및 AMD 프로세서(x86, x64).
    • 빅 엔디안: IBM 메인프레임, 일부 RISC 프로세서(예: SPARC).

앤디안 변환 예제(Javascript)

ArrayBuffer와 DataView 객체를 활용하면 효율적으로 데이터를 조작할 수 있다.

  1. 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"
    
  2. 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]
    
  3. 파일 데이터 처리에서 활용

    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.