FLAC 파일 구조 분석|fLaC 시그니처·STREAMINFO·메타데이터 확인 방법
FLAC은 음질 손실 없이 오디오 데이터를 압축하는 대표적인 무손실 오디오 파일 형식이다.
일반적으로 .flac 확장자를 사용하며 음악 보관, 음원 아카이빙, 오디오 데이터 전송 및 원본 품질 유지가 중요한 환경에서 활용된다.
FLAC 파일은 단순히 압축된 소리 데이터만 저장하지 않는다. 파일 시작에는 고정된 시그니처가 존재하고, 그 뒤에는 오디오 특성을 설명하는 메타데이터 블록과 실제 압축 오디오 프레임이 이어진다.
특히 STREAMINFO 블록에는 샘플레이트, 채널 수, 비트 깊이, 전체 샘플 수와 오디오 원본 데이터에 대한 MD5 서명 필드가 포함된다.
따라서 FLAC 파일 구조 분석에서는 fLaC 시그니처, 메타데이터 블록 헤더, STREAMINFO, 오디오 프레임 시작 위치, MD5 필드와 파일 전체 해시값을 구분해 확인해야 한다.
이번 글에서는 FLAC의 전체 구조와 메타데이터 블록, STREAMINFO 필드, 오디오 프레임, 무손실 압축 원리 및 파일 손상 검증 방법을 알아본다.
또한 Windows PowerShell 5.1을 기준으로 작성한 읽기 전용 코드로 FLAC 시그니처와 메타데이터 블록을 확인하고, STREAMINFO 정보를 해석하며 SHA-256 해시값을 계산하는 방법을 설명한다.
1. FLAC 파일 구조 분석이 필요한 이유
FLAC 파일은 무손실 오디오 형식이지만 확장자가 .flac이라는 이유만으로 파일의 정상 여부를 판단할 수는 없다.
다음과 같은 상황에서 구조 분석이 도움이 된다.
- FLAC 파일이 재생되지 않는 경우
- 음원 정보가 잘못 표시되는 경우
- 샘플레이트와 비트 깊이를 확인하려는 경우
- 메타데이터 블록이 정상적으로 저장되었는지 확인하려는 경우
- 파일 일부가 잘렸는지 점검하려는 경우
- 압축 오디오 데이터의 시작 위치를 확인하려는 경우
- STREAMINFO의 MD5 필드를 확인하려는 경우
- 파일 복사 또는 전송 후 동일성을 검증하려는 경우
FLAC 구조 분석의 핵심은 메타데이터가 정의하는 오디오 정보와 파일에 실제 저장된 구조를 단계적으로 확인하는 것이다.
단, 메타데이터 헤더가 정상이라고 해서 모든 오디오 프레임이 정상적으로 디코딩되거나 음원 전체가 손상되지 않았다는 뜻은 아니다.
2. FLAC 파일의 기본 개념과 특징
FLAC은 Free Lossless Audio Codec의 약자다.
손실 압축 방식과 달리 디코딩 후 원래의 PCM 오디오 샘플을 복원할 수 있도록 설계되었다.
대표적인 특징은 다음과 같다.
- 무손실 오디오 압축
- 일반적으로
.flac확장자 사용 - 고정된
fLaC시그니처 - STREAMINFO 메타데이터 블록 필수
- 여러 종류의 선택적 메타데이터 지원
- 압축된 오디오 프레임 저장
- 프레임 단위의 CRC 검사 필드 사용
- STREAMINFO에 디코딩된 오디오 샘플의 MD5 서명 필드 포함
FLAC은 파일 크기를 줄이면서 오디오 샘플을 손실 없이 복원하는 것을 목표로 한다.
다만 무손실 압축이라는 특성이 파일의 무결성이나 원본 출처를 자동으로 보장하는 것은 아니다.
3. FLAC 파일의 전체 구조
일반적인 네이티브 FLAC 파일은 다음과 같이 구성된다.
FLAC File
│
├── fLaC Signature (4 bytes)
│
├── Metadata Blocks
│ ├── STREAMINFO (mandatory)
│ ├── VORBIS_COMMENT (optional)
│ ├── PICTURE (optional)
│ ├── SEEKTABLE (optional)
│ └── Other Metadata Blocks
│
└── Audio Frames
├── Frame 1
├── Frame 2
├── Frame 3
└── ...
파일 시작의 fLaC 시그니처 뒤에는 하나 이상의 메타데이터 블록이 배치된다.
STREAMINFO는 첫 번째 메타데이터 블록이어야 한다.
마지막 메타데이터 블록을 나타내는 플래그를 확인하면 압축 오디오 프레임 영역이 시작되는 위치를 계산할 수 있다.
단, 파일 앞에 별도 데이터가 추가된 비표준 파일이나 다른 컨테이너에 포함된 FLAC 스트림은 이번 글의 기본 분석 대상에서 제외한다.
4. FLAC 파일 시그니처와 시작 바이트
네이티브 FLAC 파일은 다음 4바이트로 시작한다.
66 4C 61 43
ASCII 문자로 해석하면 다음과 같다.
fLaC
| 오프셋 | 크기 | 내용 |
|---|---|---|
| 0 | 4바이트 | fLaC 시그니처 |
| 4 | 4바이트 | 첫 번째 메타데이터 블록 헤더 |
| 8 | 가변 | 첫 번째 메타데이터 블록 데이터 |
파일 시작 4바이트가 일치하지 않는다면 일반적인 네이티브 FLAC 구조로 바로 해석해서는 안 된다.
그러나 시그니처가 일치한다는 사실만으로 파일 전체의 정상 여부를 판단할 수는 없다.
5. FLAC 메타데이터 블록 헤더 구조
각 FLAC 메타데이터 블록은 4바이트 헤더로 시작한다.
Metadata Block Header (4 bytes)
│
├── 1 bit : Is Last Block
├── 7 bits : Block Type
└── 24 bits: Block Length
첫 번째 바이트는 마지막 블록 여부와 블록 유형을 함께 저장한다.
나머지 3바이트는 해당 블록의 데이터 길이를 나타내는 빅엔디언 정수다.
| 필드 | 크기 | 의미 |
|---|---|---|
| Is Last Block | 1비트 | 마지막 메타데이터 블록 여부 |
| Block Type | 7비트 | 메타데이터 유형 |
| Block Length | 24비트 | 헤더를 제외한 데이터 크기 |
예를 들어 다음 헤더를 살펴보자.
80 00 00 22
첫 바이트 80은 마지막 메타데이터 블록이며 유형이 STREAMINFO(0)임을 의미한다.
뒤의 00 00 22는 데이터 길이가 34바이트임을 나타낸다.
6. 주요 FLAC 메타데이터 블록 유형
FLAC은 블록 유형 번호로 메타데이터의 종류를 구분한다.
| 유형 번호 | 이름 | 용도 |
|---|---|---|
| 0 | STREAMINFO | 오디오 스트림 기본 정보 |
| 1 | PADDING | 예약 공간 |
| 2 | APPLICATION | 애플리케이션 데이터 |
| 3 | SEEKTABLE | 탐색 지점 정보 |
| 4 | VORBIS_COMMENT | 태그 및 텍스트 메타데이터 |
| 5 | CUESHEET | 트랙·인덱스 관련 정보 |
| 6 | PICTURE | 앨범 아트 등 이미지 |
이외의 유형 번호는 규격에서 별도로 정의하거나 예약할 수 있다.
모든 FLAC 파일에 위 블록이 전부 포함되는 것은 아니다.
STREAMINFO는 필수이며, 나머지 블록은 파일의 용도에 따라 선택적으로 포함된다.
7. STREAMINFO 블록의 역할
STREAMINFO는 FLAC 파일에서 가장 중요한 메타데이터 블록이다.
정상적인 네이티브 FLAC 스트림에서 첫 번째 블록이며, 데이터 크기는 34바이트다.
대표적으로 다음 정보를 저장한다.
- 최소 블록 크기
- 최대 블록 크기
- 최소 프레임 크기
- 최대 프레임 크기
- 샘플레이트
- 채널 수
- 샘플당 비트 수
- 전체 샘플 수
- 디코딩된 오디오 샘플의 MD5 서명
STREAMINFO는 오디오 데이터의 기본적인 재생 조건과 일부 무결성 관련 정보를 제공한다.
그러나 이 블록만으로 실제 압축 프레임 전체의 정상 여부를 확인할 수는 없다.
8. STREAMINFO의 34바이트 구조
STREAMINFO 데이터는 다음과 같이 구성된다.
| 상대 오프셋 | 크기 | 필드 |
|---|---|---|
| 0 | 2바이트 | Minimum Block Size |
| 2 | 2바이트 | Maximum Block Size |
| 4 | 3바이트 | Minimum Frame Size |
| 7 | 3바이트 | Maximum Frame Size |
| 10 | 20비트 | Sample Rate |
| 12의 하위 비트 포함 | 3비트 | Channels − 1 |
| 12~13 | 5비트 | Bits Per Sample − 1 |
| 13~17 | 36비트 | Total Samples |
| 18 | 16바이트 | MD5 Signature |
샘플레이트부터 전체 샘플 수까지의 정보는 독립된 바이트 필드가 아니라 연속된 8바이트 안에 비트 단위로 압축되어 저장된다.
따라서 이 부분을 읽을 때는 빅엔디언 비트 배열과 비트 마스크를 정확하게 적용해야 한다.
9. 샘플레이트와 채널 수
샘플레이트는 1초 동안 처리되는 오디오 샘플의 수를 나타낸다.
대표적인 값은 다음과 같다.
44100 Hz
48000 Hz
96000 Hz
채널 수는 오디오 신호의 채널 개수를 나타낸다.
FLAC의 STREAMINFO에서는 실제 채널 수보다 1 작은 값을 3비트로 저장한다.
Stored Channels = 1 → Actual Channels = 2
이는 2채널 스테레오 오디오를 나타내는 예시다.
STREAMINFO에서 채널 수는 1~8 범위로 표현할 수 있다.
다만 헤더에 저장된 채널 수와 실제 오디오 프레임의 일관성은 별도로 확인해야 한다.
10. 비트 깊이와 전체 샘플 수
비트 깊이는 하나의 오디오 샘플을 표현하는 데 사용되는 비트 수다.
예를 들어 다음과 같은 값이 사용될 수 있다.
16-bit
24-bit
STREAMINFO에는 실제 비트 깊이보다 1 작은 값이 5비트로 기록된다.
Stored Bits Per Sample = 15
Actual Bits Per Sample = 16
전체 샘플 수는 36비트 필드에 저장된다.
이 값은 채널별 오디오 샘플 프레임 수를 나타내며, 0은 전체 샘플 수가 알려지지 않았음을 뜻할 수 있다.
재생 시간은 전체 샘플 수와 샘플레이트를 이용해 계산할 수 있다.
Duration = Total Samples / Sample Rate
예를 들어 다음과 같다면,
Total Samples = 4,410,000
Sample Rate = 44,100 Hz
재생 시간은 다음과 같다.
4,410,000 / 44,100 = 100 seconds
단, 전체 샘플 수가 0이거나 실제 프레임과 일치하지 않는 경우 이 계산은 정확한 재생 시간을 보장하지 않는다.
11. STREAMINFO의 MD5 서명
STREAMINFO의 마지막 16바이트에는 MD5 서명 필드가 있다.
이 값은 일반적으로 디코딩된 오디오 샘플 데이터를 대상으로 계산한다.
중요한 점은 다음과 같다.
STREAMINFO의 MD5는 FLAC 파일 전체의 MD5 해시가 아니다.
예를 들어 FLAC 파일의 태그나 앨범 아트만 변경되었다면 파일 전체의 SHA-256 값은 달라질 수 있다.
반면 디코딩된 오디오 샘플이 그대로라면 STREAMINFO의 오디오 MD5 값은 동일하게 유지될 수 있다.
단, MD5 필드가 모두 0인 경우는 MD5 서명이 제공되지 않았음을 나타낼 수 있다.
또한 MD5 필드에 값이 존재한다는 사실만으로 오디오 데이터가 검증된 것은 아니다. 실제 디코딩 후 규격에 맞게 MD5를 다시 계산하고 비교해야 한다.
12. VORBIS_COMMENT와 음악 태그
FLAC은 VORBIS_COMMENT 메타데이터 블록을 이용해 텍스트 태그를 저장할 수 있다.
대표적인 태그는 다음과 같다.
TITLE
ARTIST
ALBUM
DATE
GENRE
TRACKNUMBER
이 블록은 STREAMINFO와 달리 텍스트 정보를 중심으로 구성된다.
VORBIS_COMMENT 내부의 문자열 길이 필드는 리틀엔디언 방식으로 기록된다.
이는 FLAC 메타데이터 블록 헤더의 24비트 길이 필드가 빅엔디언인 것과 구분해야 한다.
따라서 FLAC 파일을 분석할 때는 파일 전체에 단일 바이트 순서만 적용해서는 안 된다.
13. PICTURE 블록과 앨범 아트
FLAC은 PICTURE 블록을 이용해 앨범 커버 등 이미지 데이터를 저장할 수 있다.
PICTURE 블록에는 일반적으로 다음 정보가 포함된다.
- 그림 유형
- MIME 타입
- 이미지 설명
- 이미지 너비
- 이미지 높이
- 색상 깊이
- 이미지 데이터 길이
- 실제 이미지 데이터
앨범 아트는 JPEG 또는 PNG 등 별도 이미지 형식으로 저장될 수 있다.
따라서 PICTURE 블록의 경계가 정상이라고 해도 내부 이미지 파일의 구조가 반드시 정상이라는 의미는 아니다.
이미지 무결성을 자세히 확인하려면 해당 이미지 형식의 시그니처와 내부 구조를 추가 분석해야 한다.
14. SEEKTABLE과 탐색 정보
SEEKTABLE은 오디오 재생 위치를 빠르게 이동하기 위한 탐색 지점 정보를 저장한다.
탐색 지점에는 일반적으로 다음과 같은 값이 포함된다.
- 샘플 번호
- 해당 프레임의 오프셋
- 대상 프레임의 샘플 수
SEEKTABLE이 존재하면 디코더가 특정 위치로 이동하는 데 도움이 될 수 있다.
하지만 모든 FLAC 파일에 SEEKTABLE이 필요한 것은 아니다.
SEEKTABLE이 없더라도 정상적으로 재생할 수 있는 FLAC 파일이 존재한다.
15. FLAC 오디오 프레임의 기본 구조
메타데이터 블록 영역이 끝나면 압축된 오디오 프레임이 이어진다.
일반적인 프레임은 다음 요소로 구성된다.
FLAC Audio Frame
│
├── Frame Header
├── Subframe Data
│ ├── Channel 1
│ ├── Channel 2
│ └── ...
└── Frame Footer
프레임 헤더에는 동기화 패턴과 오디오 처리 관련 정보가 포함된다.
서브프레임에는 실제 압축 오디오 샘플을 복원하기 위한 데이터가 저장된다.
프레임 헤더와 프레임 푸터에는 각각 CRC-8과 CRC-16 검사 필드가 사용된다.
다만 CRC는 오류 탐지를 위한 장치이며 암호학적 무결성이나 파일의 출처를 보장하는 수단은 아니다.
16. FLAC 파일의 기본 구조 검증 순서
FLAC 파일을 분석할 때는 다음 순서로 확인하는 것이 좋다.
① 파일 길이 확인
최소 4바이트 시그니처와 첫 번째 메타데이터 헤더가 존재하는지 확인한다.
② fLaC 시그니처 확인
파일 시작 바이트가 66 4C 61 43인지 확인한다.
③ 첫 번째 메타데이터 블록 확인
첫 번째 블록이 STREAMINFO인지 확인한다.
④ STREAMINFO 길이 확인
STREAMINFO 데이터 길이가 34바이트인지 확인한다.
⑤ 메타데이터 블록 순회
각 블록의 유형, 길이와 파일 경계를 확인한다.
⑥ 마지막 메타데이터 블록 확인
마지막 블록 플래그를 이용해 오디오 프레임 시작 위치를 계산한다.
⑦ STREAMINFO 값 해석
샘플레이트, 채널 수, 비트 깊이, 전체 샘플 수와 MD5 필드를 확인한다.
⑧ 오디오 무결성 확인
필요한 경우 실제 오디오를 디코딩하여 프레임 오류와 오디오 MD5 일치 여부를 확인한다.
⑨ 파일 동일성 확인
신뢰할 수 있는 원본 파일의 SHA-256과 비교한다.
17. PowerShell 5.1로 fLaC 시그니처 확인하기
첫 번째 실습에서는 FLAC 파일의 시작 4바이트를 읽어 기본 시그니처를 확인한다.
① 실습 파일
C:\FileTest\sample.flac
실행할 때 실제 FLAC 파일 경로로 변경한다.
② PowerShell 코드
$path = "C:\FileTest\sample.flac"
$stream = [System.IO.File]::OpenRead($path)
try {
$reader = New-Object System.IO.BinaryReader($stream)
if ($stream.Length -lt 8) {
throw "FLAC file is too short."
}
$signature = $reader.ReadBytes(4)
$signatureText = [System.Text.Encoding]::ASCII.GetString($signature)
if ($signatureText -ne "fLaC") {
throw "Not a native FLAC signature."
}
[PSCustomObject]@{
Signature = $signatureText
SignatureHex = [BitConverter]::ToString($signature)
FileSize = $stream.Length
SignatureValid = $true
}
}
finally {
$stream.Dispose()
}
③ 출력 예시
Signature : fLaC
SignatureHex : 66-4C-61-43
FileSize : 8500000
SignatureValid : True
위 값은 구조 설명을 위한 예시다.
④ 코드 해석
파일 시작 4바이트를 읽어 ASCII 문자열 fLaC와 비교한다.
⑤ 코드의 한계
이 코드는 파일 시작 시그니처만 확인한다.
STREAMINFO, 오디오 프레임, CRC 또는 MD5 무결성은 검증하지 않는다.
18. PowerShell 5.1로 메타데이터 블록 목록 확인하기
두 번째 실습에서는 메타데이터 블록을 순회하여 블록 유형과 길이, 마지막 블록 여부 및 오디오 데이터 시작 위치를 확인한다.
① PowerShell 코드
$path = "C:\FileTest\sample.flac"
$stream = [System.IO.File]::OpenRead($path)
try {
$reader = New-Object System.IO.BinaryReader($stream)
if ($stream.Length -lt 8) {
throw "FLAC file is too short."
}
$signature = [System.Text.Encoding]::ASCII.GetString(
$reader.ReadBytes(4)
)
if ($signature -ne "fLaC") {
throw "Invalid FLAC signature."
}
$blockIndex = 0
$isLast = $false
$results = @()
while (-not $isLast) {
if (($stream.Length - $stream.Position) -lt 4) {
throw "Metadata header exceeds file length."
}
$header = $reader.ReadBytes(4)
$isLast = (($header[0] -band 0x80) -ne 0)
$blockType = $header[0] -band 0x7F
$blockLength = (
([int64]$header[1] -shl 16) -bor
([int64]$header[2] -shl 8) -bor
[int64]$header[3]
)
$dataStart = $stream.Position
$dataEnd = $dataStart + $blockLength
if ($dataEnd -gt $stream.Length) {
throw "Metadata block exceeds file length."
}
if ($blockIndex -eq 0 -and
($blockType -ne 0 -or $blockLength -ne 34)) {
throw "First metadata block is not valid STREAMINFO."
}
$results += [PSCustomObject]@{
Block = $blockIndex + 1
Type = $blockType
DataLength = $blockLength
DataOffset = $dataStart
LastBlock = $isLast
}
$stream.Position = $dataEnd
$blockIndex++
}
$results | Format-Table -AutoSize
"Audio data begins at byte offset: $($stream.Position)"
}
finally {
$stream.Dispose()
}
② 출력 예시
Block Type DataLength DataOffset LastBlock
----- ---- ---------- ---------- ---------
1 0 34 8 False
2 4 120 46 True
Audio data begins at byte offset: 166
위 값은 설명을 위한 예시다.
③ 코드 해석
각 메타데이터 블록의 헤더를 읽고 24비트 빅엔디언 길이 필드를 계산한다.
마지막 블록 플래그가 설정될 때까지 반복하며, 마지막 블록의 끝 위치를 오디오 프레임 시작 위치로 표시한다.
④ 코드의 한계
이 코드는 메타데이터 블록의 기본 경계만 확인한다.
개별 블록의 내부 필드나 실제 오디오 프레임의 유효성을 완전히 검증하지 않는다.
19. PowerShell 5.1로 STREAMINFO 주요 정보 확인하기
세 번째 실습에서는 STREAMINFO의 34바이트 데이터를 읽어 샘플레이트, 채널 수, 비트 깊이, 전체 샘플 수와 MD5 필드를 확인한다.
① PowerShell 코드
$path = "C:\FileTest\sample.flac"
$stream = [System.IO.File]::OpenRead($path)
try {
$reader = New-Object System.IO.BinaryReader($stream)
if ($stream.Length -lt 42) {
throw "FLAC STREAMINFO area is incomplete."
}
$signature = [System.Text.Encoding]::ASCII.GetString(
$reader.ReadBytes(4)
)
if ($signature -ne "fLaC") {
throw "Invalid FLAC signature."
}
$header = $reader.ReadBytes(4)
$blockType = $header[0] -band 0x7F
$blockLength = (
([int]$header[1] -shl 16) -bor
([int]$header[2] -shl 8) -bor
[int]$header[3]
)
if ($blockType -ne 0 -or $blockLength -ne 34) {
throw "First block is not STREAMINFO."
}
$data = $reader.ReadBytes(34)
if ($data.Length -ne 34) {
throw "Incomplete STREAMINFO."
}
$minBlockSize = ([int]$data[0] -shl 8) -bor [int]$data[1]
$maxBlockSize = ([int]$data[2] -shl 8) -bor [int]$data[3]
$sampleRate = (
([int]$data[10] -shl 12) -bor
([int]$data[11] -shl 4) -bor
([int]$data[12] -shr 4)
)
$channels = (($data[12] -band 0x0E) -shr 1) + 1
$bitsPerSample = (
(([int]$data[12] -band 0x01) -shl 4) -bor
(([int]$data[13] -band 0xF0) -shr 4)
) + 1
$totalSamples = (
([int64]($data[13] -band 0x0F) -shl 32) -bor
([int64]$data[14] -shl 24) -bor
([int64]$data[15] -shl 16) -bor
([int64]$data[16] -shl 8) -bor
[int64]$data[17]
)
$md5Bytes = New-Object byte[] 16
[Array]::Copy($data, 18, $md5Bytes, 0, 16)
$md5Hex = ([BitConverter]::ToString($md5Bytes)).Replace("-", "").ToLowerInvariant()
$duration = $null
if ($sampleRate -gt 0 -and $totalSamples -gt 0) {
$duration = [Math]::Round(
([double]$totalSamples / [double]$sampleRate), 3
)
}
[PSCustomObject]@{
MinimumBlockSize = $minBlockSize
MaximumBlockSize = $maxBlockSize
SampleRateHz = $sampleRate
Channels = $channels
BitsPerSample = $bitsPerSample
TotalSamples = $totalSamples
DurationSeconds = $duration
AudioMD5Field = $md5Hex
}
}
finally {
$stream.Dispose()
}
② 출력 예시
MinimumBlockSize : 4096
MaximumBlockSize : 4096
SampleRateHz : 44100
Channels : 2
BitsPerSample : 16
TotalSamples : 4410000
DurationSeconds : 100
AudioMD5Field : (32자리 16진수 MD5 값)
위 값은 설명을 위한 예시다.
③ 코드 해석
STREAMINFO에 저장된 비트 필드를 마스크와 시프트 연산으로 해석한다.
샘플레이트, 채널 수, 비트 깊이와 전체 샘플 수를 계산하고 16바이트 MD5 필드를 16진수 문자열로 출력한다.
④ 코드의 한계
이 코드는 STREAMINFO에 기록된 값을 읽는다.
실제 오디오 데이터를 디코딩하지 않으므로 MD5 일치 여부나 프레임 오류를 검증하지 않는다.
또한 샘플레이트, 블록 크기 등의 값이 규격상 허용되는지에 대한 모든 조건을 검사하지는 않는다.
20. FLAC 파일 손상 시 확인할 항목
FLAC 파일이 재생되지 않거나 메타데이터가 비정상적으로 표시된다면 다음 항목을 점검할 수 있다.
| 점검 항목 | 확인 목적 |
|---|---|
| fLaC Signature | 파일 형식 식별 |
| Metadata Header | 블록 헤더 구조 |
| Last Block Flag | 메타데이터 종료 |
| Block Type | 블록 유형 |
| Block Length | 데이터 길이 |
| STREAMINFO | 오디오 기본 정보 |
| Sample Rate | 샘플레이트 |
| Channels | 채널 수 |
| Bits Per Sample | 비트 깊이 |
| Total Samples | 전체 샘플 수 |
| Audio MD5 Field | 오디오 MD5 서명 |
| Audio Frames | 압축 오디오 데이터 |
| Frame CRC | 프레임 오류 탐지 |
| SHA-256 | 파일 전체 동일성 |
대표적인 손상 상황
① 시그니처 오류
파일 시작이 fLaC와 일치하지 않으면 일반적인 네이티브 FLAC 구조로 바로 해석하기 어렵다.
② STREAMINFO 누락 또는 길이 오류
첫 번째 메타데이터 블록이 STREAMINFO가 아니거나 길이가 34바이트가 아니라면 정상적인 구조가 아니다.
③ 메타데이터 길이 오류
블록 길이가 실제 파일 범위를 초과하면 파일이 잘렸거나 길이 필드가 손상되었을 수 있다.
④ 메타데이터 종료 플래그 오류
마지막 블록 표시가 잘못되면 오디오 프레임 시작 위치를 정확히 찾지 못할 수 있다.
⑤ 오디오 프레임 손상
메타데이터가 정상이어도 오디오 프레임이 손상되면 재생 중 오류가 발생할 수 있다.
⑥ 오디오 MD5 불일치
정상적인 디코딩을 통해 계산한 오디오 MD5와 STREAMINFO의 유효한 기준값이 다르다면 오디오 데이터의 변경이나 손상을 의심할 수 있다.
21. FLAC 구조 검증과 SHA-256 무결성 검증
FLAC 구조 분석, 오디오 MD5 검증, SHA-256 비교는 서로 목적이 다르다.
구조 분석
시그니처와 메타데이터 블록의 위치, 길이, STREAMINFO 필드를 확인한다.
오디오 MD5 검증
FLAC을 실제로 디코딩한 후 규격에 맞게 계산한 오디오 샘플의 MD5 값을 STREAMINFO의 값과 비교한다.
SHA-256 검증
FLAC 파일 전체의 바이트를 대상으로 해시값을 계산해 신뢰할 수 있는 원본과 비교한다.
PowerShell 5.1 코드
$path = "C:\FileTest\sample.flac"
Get-FileHash -LiteralPath $path -Algorithm SHA256 |
Format-List Algorithm, Hash, Path
검증 방식 비교
| 구분 | FLAC 구조 분석 | 오디오 MD5 | SHA-256 |
|---|---|---|---|
| 확인 대상 | 헤더·메타데이터 | 디코딩된 오디오 | 파일 전체 |
| 오디오 디코딩 필요 | 아니오 | 예 | 아니오 |
| 태그 변경 영향 | 구조에 따라 다름 | 오디오 동일 시 일반적으로 없음 | 있음 |
| 오디오 손상 탐지 | 제한적 | 기준값이 유효할 때 가능 | 기준 해시와 비교 시 가능 |
| 파일 출처 증명 | 불가 | 불가 | 해시만으로는 불가 |
| 파일 안전성 보장 | 불가 | 불가 | 불가 |
SHA-256이 신뢰할 수 있는 기준값과 일치하면 파일 전체가 동일하다고 매우 높은 신뢰도로 판단할 수 있다.
하지만 SHA-256은 파일 내부의 오디오가 정상적으로 재생되는지 자체를 판단하지 않는다.
22. 자주 묻는 질문
Q1. FLAC 파일은 무엇인가요?
원래의 오디오 샘플을 손실 없이 복원할 수 있도록 설계된 무손실 오디오 압축 형식이다.
Q2. FLAC 파일의 시작 바이트는 무엇인가요?
일반적인 네이티브 FLAC 파일은 66 4C 61 43으로 시작하며 ASCII로 fLaC를 의미한다.
Q3. STREAMINFO는 무엇인가요?
샘플레이트, 채널 수, 비트 깊이, 전체 샘플 수와 오디오 MD5 필드 등을 저장하는 필수 메타데이터 블록이다.
Q4. STREAMINFO의 크기는 얼마인가요?
메타데이터 블록 헤더 4바이트를 제외한 데이터 영역은 34바이트다.
Q5. FLAC 파일의 MD5와 파일 전체의 MD5는 같은가요?
아니다. STREAMINFO의 MD5는 디코딩된 오디오 샘플을 대상으로 하는 서명 필드다.
Q6. FLAC 파일에 앨범 아트가 들어갈 수 있나요?
가능하다. PICTURE 메타데이터 블록에 이미지 정보와 데이터가 저장될 수 있다.
Q7. FLAC 메타데이터의 바이트 순서는 모두 같은가요?
아니다. 메타데이터 블록 길이는 빅엔디언이지만 VORBIS_COMMENT 내부 길이 필드는 리틀엔디언이다.
Q8. STREAMINFO가 정상이면 FLAC 파일도 정상인가요?
아니다. 실제 오디오 프레임의 손상 여부는 별도로 확인해야 한다.
Q9. PowerShell 5.1만으로 FLAC 전체의 무결성을 확인할 수 있나요?
이번 코드로는 시그니처, 메타데이터 경계, STREAMINFO 값과 파일 전체 SHA-256을 확인할 수 있다. 오디오 프레임 전체와 오디오 MD5 검증에는 별도의 디코딩 과정이 필요하다.
마무리
FLAC은 fLaC 시그니처와 메타데이터 블록, 압축 오디오 프레임으로 구성되는 무손실 오디오 파일 형식이다.
FLAC 파일 구조 분석에서는 첫 번째 STREAMINFO 블록의 존재, 메타데이터 길이와 경계, 마지막 블록 플래그, 샘플레이트·채널 수·비트 깊이·전체 샘플 수를 순서대로 확인하는 것이 중요하다.
특히 STREAMINFO의 MD5 필드와 파일 전체의 SHA-256은 서로 다른 대상을 검증한다는 점을 이해해야 한다.
메타데이터가 정상이라고 해서 모든 오디오 프레임이 정상적으로 디코딩되는 것은 아니며, 해시값이 존재한다는 사실만으로 파일의 안전성이나 출처가 보장되는 것도 아니다.
따라서 FLAC의 구조 분석, 실제 오디오 디코딩 검증, 오디오 MD5 비교 및 파일 전체 SHA-256 검증을 목적에 맞게 구분해 사용하는 것이 바람직하다.
관련 글 함께 읽기
오디오 파일 구조를 더 자세히 이해하려면 WAV 파일 구조 분석과 MP3 파일 구조 분석 글을 함께 참고할 수 있다.
※ 위 두 글 제목에는 실제 사이트의 공개된 글 URL을 내부 링크로 연결한다. 연결 후 이 안내 문구는 삭제한다.
핵심 내용 3줄 요약
- FLAC은
fLaC시그니처, STREAMINFO를 포함한 메타데이터 블록과 압축 오디오 프레임으로 구성된다. - 메타데이터 헤더와 STREAMINFO를 해석하면 샘플레이트, 채널 수, 비트 깊이, 전체 샘플 수와 오디오 데이터 시작 위치를 확인할 수 있다.
- STREAMINFO의 오디오 MD5와 파일 전체 SHA-256은 검증 대상이 다르며, 실제 오디오 손상 검증에는 디코딩 과정이 필요하다.
공식 및 기술 참고자료
- FLAC 공식 사이트 — Format Specification
https://xiph.org/flac/format.html - IETF — RFC 9639: Free Lossless Audio Codec (FLAC)
https://www.rfc-editor.org/rfc/rfc9639.html - Xiph.Org — FLAC 프로젝트
https://xiph.org/flac/ - Microsoft Learn — BinaryReader Class
https://learn.microsoft.com/dotnet/api/system.io.binaryreader - Microsoft Learn — File.OpenRead Method
https://learn.microsoft.com/dotnet/api/system.io.file.openread - Microsoft Learn — Get-FileHash (PowerShell 5.1)
https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/get-filehash?view=powershell-5.1
※ 본문의 PowerShell 코드는 네이티브 FLAC의 기본 구조를 읽기 전용으로 분석하는 학습용 예시다. 전체 오디오 프레임을 디코딩하거나 오디오 MD5를 재계산하는 검증기는 아니다. Windows PowerShell 5.1 실제 실행 테스트는 별도로 필요하다.
디지털 파일 검증 연구소
댓글 0
첫 댓글을 남겨보세요.