C 언어로 JPEG 파일 판별하기 - 파일 시그니처를 읽는 법
우리가 컴퓨터에서 다루는 파일은 텍스트, 이미지, 영상 등 다양하다. 이 중 JPEG 파일은 이미지 파일 형식 중 하나다. 그런데 신기하게도, JPEG 파일의 시작 부분에는 "나는 JPEG이야!"라는 표시 같은 특별한 코드가 숨어 있다. 이걸 시그니처(signature) 라고 부른다.
이번에는 이 시그니처를 확인해서, 특정 파일이 JPEG인지 판별하는 아주 간단한 프로그램을 만들어보았다(:
파일이 JPEG인지 확인하는 C 코드
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
return 1;
}
FILE *file = fopen(argv[1], "r");
if (file == NULL)
{
return 1;
}
unsigned char bytes[3];
fread(bytes, 3, 1, file);
if (bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff)
{
printf("Maybe\n");
}
else
{
printf("No\n");
}
fclose(file);
}
하나씩 뜯어보기:)
int main(int argc, char *argv[])
C 프로그램의 시작점이다. 여기서 argc는 명령줄에서 받은 인자의 개수를 의미한다. argv는 그 인자들을 담고 있는 배열이다.
예를 들어 터미널에서 아래처럼 실행한다고 하면:
./check photo.jpg
- argc는 2
- argv[0]는 ./check
- argv[1]는 "photo.jpg"
우리는 파일 이름을 두 번째 인자로 받을 거기 때문에 argv[1]을 사용한다.
fopen(argv[1], "r")
fopen은 파일을 여는 함수다. 여기서 "r"은 읽기 모드(read) 를 의미한다. 파일을 열 수 없으면 NULL을 반환하기 때문에, 바로 체크해서 오류를 처리한다.
unsigned char bytes[3]
여기서 bytes는 크기가 3인 배열이다. 파일에서 처음 3바이트만 읽어서 여기에 저장하려는 목적이다.
그런데 왜 unsigned char일까?+_+
- char는 기본적으로 -128부터 +127까지 저장한다.
- 하지만 우리는 이미지 파일 안의 바이트 값들을 정확하게 비교해야 한다. JPEG 시그니처는 0xFF, 0xD8, 0xFF인데, 이건 0부터 255 사이의 숫자다.
- 그래서 부호 없는 정수인 unsigned char를 사용한다. 이 자료형은 0~255를 저장할 수 있다.
💡 참고: 126은 signed char에서도 unsigned char에서도 표현할 수 있다. 다만 JPEG 시그니처처럼 128 이상의 값을 다루려면 unsigned가 필요하다.
fread(bytes, 3, 1, file)
- bytes: 데이터를 저장할 배열
- 3: 바이트 단위로 3개를
- 1: 한 번만
- file: 어떤 파일에서 읽을지
즉, file에서 처음 3바이트를 bytes 배열에 저장하라는 의미다.
if (bytes[0] == 0xff && bytes[1] == 0xd8 && bytes[2] == 0xff)
JPEG 파일은 시작할 때 반드시 이 3개의 바이트로 시작한다.
- 0xFF (255)
- 0xD8 (216)
- 0xFF (255)
그래서 이 3바이트를 체크하면 "이거 JPEG일 수도 있겠다"는 판단을 할 수 있다.
결과 출력
- 조건이 맞으면: Maybe
- 아니라면: No
확정적으로 JPEG인지 알 수는 없지만, 시그니처가 맞으면 JPEG일 가능성이 있다.
JPEG만 그런가?
JPEG 외에도 많은 파일들이 시그니처를 가지고 있다. 예를 들어:
- PNG: 0x89 0x50 0x4E 0x47
- PDF: %PDF
- ZIP: PK\x03\x04
파일을 열어보고 첫 바이트들을 비교하면, 어떤 형식인지 유추할 수 있다. 이걸 활용하면 바이러스 검사, 파일 복원 등 다양한 분야에 쓰일 수 있다는 것🥰.
'IT' 카테고리의 다른 글
동적 배열 크기 변경: malloc과 realloc로 메모리 할당하기 (0) | 2025.04.13 |
---|---|
포인터와 malloc 함수 이해하기 (0) | 2025.04.09 |
인스타그램 바이럴 마케팅 하는 방법 (2025) (0) | 2025.04.03 |
C에서 사용자 입력을 받아 파일에 저장하는 방법 - scanf, fopen, fprintf 사용법 (0) | 2025.04.02 |
스택과 힙의 차이점 이해하기: 포인터를 이용한 메모리 교환 방법 (0) | 2025.03.30 |
댓글
이 글 공유하기
다른 글
-
동적 배열 크기 변경: malloc과 realloc로 메모리 할당하기
동적 배열 크기 변경: malloc과 realloc로 메모리 할당하기
2025.04.13 -
포인터와 malloc 함수 이해하기
포인터와 malloc 함수 이해하기
2025.04.09 -
인스타그램 바이럴 마케팅 하는 방법 (2025)
인스타그램 바이럴 마케팅 하는 방법 (2025)
2025.04.03 -
C에서 사용자 입력을 받아 파일에 저장하는 방법 - scanf, fopen, fprintf 사용법
C에서 사용자 입력을 받아 파일에 저장하는 방법 - scanf, fopen, fprintf 사용법
2025.04.02