현재 위치: > 최신 기사 목록> 동일한 팩 () 함수가 다른 플랫폼에서 다른 데이터를 포장 한 이유는 무엇입니까?

동일한 팩 () 함수가 다른 플랫폼에서 다른 데이터를 포장 한 이유는 무엇입니까?

M66 2025-06-03

PHP에서 Pack () 함수는 데이터를 이진 문자열로 변환하는 데 매우 유용한 도구이며, 이는 네트워크 전송 또는 파일 작업에 사용하기에 편리합니다. 그러나 많은 개발자들은 다른 플랫폼 (예 : Windows, Linux 및 MACOS)에서 동일한 팩 () 기능을 사용하면 때로는 이진 데이터가 정확히 동일하지 않다는 것을 발견했습니다. 이게 왜? 이 기사는 기본 메커니즘, 플랫폼 차이 및 솔루션의 관점에서 자세히 분석 할 것입니다.

1. Pack () 함수의 역할과 기본 사용법

Pack () 함수는 지정된 형식에 따라 하나 이상의 데이터를 이진 문자열로 패키지합니다. 일반적인 형식은 다음과 같습니다.

  • C : 서명 된 캐릭터 (1 바이트)

  • C : 서명되지 않은 문자 (1 바이트)

  • S : 서명 된 짧은 정수 (2 바이트)

  • S : 서명되지 않은 짧은 정수 (2 바이트)

  • L : 서명 긴 정수 (4 바이트)

  • L : 서명되지 않은 긴 정수 (4 바이트)

  • F : 단일 정밀 부동 소수점 번호 (4 바이트)

  • D : 이중 정밀 플로팅 포인트 번호 (8 바이트)

예를 들어:

 $data = pack("Nn", 0x12345678, 0x1234);
echo bin2hex($data);

이 코드는 네트워크 엔지니어 (Big-Endian)의 정수를 포장하며 결과는 모든 플랫폼에서 일관성이 있어야합니다.

2. 왜 동일한 코드가 다른 플랫폼에서 다르게 출력합니까?

차이는 주로 플랫폼 바이트 주문 및 기본적으로 데이터 유형 크기에 의존하는 팩 () 형식의 기호가 다음과 같이 기본적으로 있기 때문입니다.

  • SS : 바이트 순서와 크기는 플랫폼에 의존하는 "짧은 정수"에 해당합니다 (일반적으로 2 바이트이지만 플랫폼이 거의 다를 수 있음).

  • LL : "긴 정수"에 해당하며 크기와 엔디 니스는 플랫폼, 일반적으로 4 바이트에 따라 다르지만 일부 플랫폼은 8 바이트 일 수 있습니다.

또한 Endian Order에는 두 가지 주류가 있습니다.

  • Big-Endian : 높은 바이트는 낮은 주소로 저장됩니다

  • Little-Endian : 낮은 바이트는 낮은 주소로 저장됩니다

다른 플랫폼의 CPU는 다른 엔지니어를 사용합니다.

플랫폼/아키텍처 바이트 순서
Windows (x86/x64) 리틀 엔디언
리눅스 (x86/x64) 리틀 엔디언
마코스 (인텔) 리틀 엔디언
마코스 (팔) 리틀 엔디언
일부 임베디드 플랫폼 아마도 빅 엔디 안

pack ()​​sl은 기계의 기본 엔지니어에 따라 달라 지므로 동일한 코드의 출력은 다른 아키텍처 또는 운영 체제에서 다릅니다.

3. 설명 할 구체적인 예를 제시하십시오

 <?php
// 짧은 정수를 포장하십시오 0x1234
$data = pack("s", 0x1234);
echo bin2hex($data);
?>
  • 소규모 엔디 언 플랫폼 (대부분의 x86 Windows/Linux 등)에서 출력은 다음과 같습니다. 3412

  • 빅 엔디 언 플랫폼의 출력 결과는 다음과 같습니다. 1234

이것은 S가 플랫폼 엔지니어에 의존하기 때문입니다.

4. 크로스 플랫폼 일관성을 보장하는 방법은 무엇입니까?

Pack () 의 ​​출력 데이터가 플랫폼에서 일관되도록하는 것이 좋습니다.

  1. 바이트 순서를 지정하는 데 포맷터를 사용하십시오

PHP는 네트워크 바이트 주문 형식을 제공합니다.

  • N : 서명되지 않은 짧은 정수 (16 비트), 네트워크 엔디 언 (Big Endian)

  • N : 서명되지 않은 긴 정수 (32 비트), 네트워크 엔지니어 (Big Endian)

네이티브 엔지니어에 의존하는 SL을 사용하지 말고 대신 NN을 사용하십시오.

  1. 바이트 주문 변환을 사용자 정의하십시오

네이티브 엔디 어 형식을 사용해야하는 경우 먼저 pack ()를 사용한 다음 unpack ()strrev () 와 같은 함수를 사용하여 엔디 언을 수동으로 변환 할 수 있습니다.

  1. 명확한 데이터 크기

데이터 크기가 불확실한 경우 SL을 사용하지 않고 대신 SL (서명되지 않은)을 사용하여 네트워크 엔지니어와 결합하는 것이 가장 좋습니다.

5. 크로스 플랫폼 일관된 포장 방법 인 샘플 코드

 <?php
// 네트워크 엔지니어를 사용하여 크로스 플랫폼 일관성을 보장하십시오
$short = 0x1234;
$long = 0x12345678;

// pack서명되지 않은 짧은 정수와 서명되지 않은 긴 정수,모든 네트워크 바이트 순서(빅 엔디언)
$data = pack("nN", $short, $long);

// 16 진수 문자열을 인쇄하십시오
echo bin2hex($data);
?>

Windows, Linux 또는 MacOS에서 실행 되든 출력은 다음과 같습니다.

 123412345678

6. 요약

  • Pack () 의 ​​일부 형태는 플랫폼 엔지니어 및 데이터 크기에 의존하여 크로스 플랫폼 출력이 일치하지 않습니다.

  • 일반적으로 사용되는 형식 S , S , LL은 다른 시스템에서 다르게 수행 될 수 있습니다.

  • 네트워크 바이트 주문 형식 NN을 사용하면 데이터의 교차 플랫폼 일관성을 보장 할 수 있습니다.

  • 플랫폼 바이트 주문 및 데이터 유형 크기를 이해하는 것은 크로스 플랫폼 바이너리 데이터 오류를 피하기위한 핵심입니다.

이러한 세부 사항을 이해하면 이진 데이터의 구조를보다 잘 제어 할 수 있으며 다양한 프로그램 환경에서 호환성 문제를 피할 수 있습니다.