P32 확장자와 앞 8바이트 대조 실습
버전 p32-header-audit-v1
패키지 v2 경로 검사 보완 및 재검증: 2026년 10월 10일 KST / 2026년 10월 9일 UTC. Linux CPython 3.12.14에서 자동시험 18개와 기존 합성 입력 18개의 기대값을 다시 확인했습니다.
PDF 출처 보완 2026년 10월 9일 UTC: source_links.txt의 RFC 8118 8절과 미국 의회도서관 자료를 직접 열람했습니다. 정보성 MIME 등록 설명과 형식 자료이며 정식 ISO 규격 전문 열람이나 실제 PDF 버전 인증은 아닙니다.
작성 및 실행 검수 2026년 10월 9일 KST / 2026년 10월 8일 UTC
실행 환경 Linux CPython 3.12.14. 외부 패키지와 앱 설치 없음.

목적
파일 이름의 마지막 확장자와 지원하는 앞부분 표식을 비교합니다.
정상 파일 판정, 전체 파일 형식 인증, 악성코드 검사, 열기/실행/추출 안전성 판정은 하지 않습니다.
.png, .pdf, .zip만 비교합니다. .xlsx, .docx, .exe, .bin과 확장자 없는 이름은 내용도 읽지 않고 지원안함으로 기록합니다.

압축을 푼 최상위 폴더에서 실행
python3 --version
python3 header_audit.py --output report_01.json samples/01_known.png samples/02_named_pdf.pdf samples/03_unknown.bin

기대 요약
selected_files 3, total_header_bytes 16
HEADER_AGREES 1, HEADER_DIFFERS 1, INCONCLUSIVE 0, UNSUPPORTED_EXTENSION 1, SKIPPED 0, READ_ERROR 0
exit 0은 JSON을 저장했다는 뜻입니다. 모든 파일이 정상이라는 뜻이 아닙니다.
report_01.json을 텍스트 편집기로 읽고 rows의 name, suffix, head_hex, status, observed_header를 대조하세요.

다시 실행
같은 report_01.json으로 실행하면 STOP FileExistsError와 exit 2로 멈춥니다.
새 결과가 필요하면 --output report_02.json처럼 새 이름을 지정하세요. 기존 출력은 지우지 않습니다.
출력 이름은 .json으로 끝나야 하고 어떤 입력 경로와도 같으면 안 됩니다. 출력 폴더는 먼저 존재해야 합니다.
입력과 출력 경로에 상위 폴더를 뜻하는 '..' 구성요소를 사용하지 마세요. 지원 입력의 해당 경로는 내용 읽기 없이 SKIPPED, read_note PARENT_COMPONENT로 남깁니다. 출력 경로에 '..'가 있으면 저장하지 않고 STOP ValueError와 exit 2로 멈춥니다.

한계 반례를 직접 실행
python3 header_audit.py --output limits_01.json samples/04_header_only.png samples/05_short.png samples/06_prefix_only.pdf samples/07_offset.pdf samples/08_normal.zip samples/09_empty.zip samples/10_marker.zip samples/11_broken.zip samples/12_office_container.xlsx samples/13_unknown.pdf samples/14_zero.png samples/15_mutated.png samples/16_uppercase.PDF samples/17_report.pdf.exe samples/18_no_extension

expected.json에는 기본 요약과 18개 독립 기대값이 있습니다.
04_header_only.png는 PNG 표식 8바이트뿐이어도 HEADER_AGREES입니다. 유효한 이미지가 아닙니다.
06_prefix_only.pdf는 %PDF-1.7 8바이트뿐입니다. 16_uppercase.PDF는 %PDF-XYZ 임의 바이트입니다. 둘 다 PDF_PREFIX 관측이며 버전이나 PDF 본문 인증이 아닙니다.
07_offset.pdf는 첫 8바이트 뒤에 %PDF-1.7이 있어도 INCONCLUSIVE입니다. 이 도구는 오프셋 0만 봅니다.
10_marker.zip와 11_broken.zip의 ZIP 표식 대응은 ZIP 유효성이나 추출 가능성을 뜻하지 않습니다.
12_office_container.xlsx는 ZIP 바이트를 담은 합성 파일이며 실제 통합문서가 아닙니다. .xlsx는 지원하지 않으므로 내용 읽기 0입니다.

시험
python3 -m unittest discover -v
초기 검수에서는 자동시험 17개로 입력/출력 충돌, 1~100개 경로, 출력 바이트 제한, 링크/폴더/FIFO 정책 등을 확인했습니다. v2 재검증은 '..' 경로 거부 회귀시험 한 개를 추가한 자동시험 18개입니다. 일반 ../경로와 alias/../경로에서 실제 파일 읽기 0과 원본 SHA 보존, 해당 출력 경로의 생성 거부를 확인합니다. 파일 이름 180문자 허용과 181문자 거부는 별도 경계 검수로 확인했습니다.
Windows와 실제 Office 앱은 이 패키지의 검수에서 실행하지 않았습니다.
Windows Python Launcher에 3.12가 설치돼 있다면 명령의 python3을 py -3.12로 바꿔 사용할 수 있습니다. 해당 경로의 실제 실행은 별도로 확인해야 합니다.

자원과 파일 정책
명시한 경로 1~100개. 폴더 재귀 탐색 없음. 파일 이름은 최대 180문자.
지원 확장자의 일반 파일에서 unbuffered binary read로 최대 8바이트를 요청합니다. 100개에서 반환 내용 최대 800바이트.
OS의 디스크 선읽기와 실제 물리 I/O 양은 측정하지 않습니다.
JSON은 저장 전 최대 131072바이트 제한을 검사하고 xb로 새 파일만 만듭니다.
심볼릭 링크, junction과 이들을 포함하는 경로, 폴더, FIFO를 지원하지 않습니다. 링크와 일반 파일 상태 검사는 악의적 동시 경로 교체를 차단하는 보안 경계가 아닙니다. 별도 연습 폴더의 변하지 않는 합성 입력에서 사용하세요.
지원 입력에서는 '..' 구성요소를 링크 검사보다 먼저 거부해, 경로 정규화로 링크 구성요소가 사라지는 경우도 읽지 않습니다. 지원하지 않는 확장자는 종전대로 내용 읽기 없이 UNSUPPORTED_EXTENSION입니다.
원본 파일을 쓰거나 이름을 바꾸거나 이동하거나 삭제하는 코드가 없습니다. 읽기로 파일시스템의 접근 시각은 바뀔 수 있습니다.
저장 도중 디스크 용량이나 권한 문제가 생기면 새 JSON 일부가 남을 수 있습니다. 그 파일을 완료 결과로 사용하지 말고 원인을 해결한 뒤 다른 새 이름으로 실행하세요.

파일 목록
header_audit.py 전체 실행 코드
test_header_audit.py 자동시험
expected.json 독립 기대값
samples/01~18 합성 입력
source_links.txt 공식 출처와 확인 범위
SHA256SUMS.txt 배포 파일 체크섬
