using System; using System.IO; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using Paca.Mobile.Core; using Xunit; namespace Paca.Tests.Mobile; /// /// 모바일 미디어 라이브러리 고속 무결성 검증 및 포맷 헤더 분석 게이트 (Gate 191 ~ Gate 194) /// public class MobileMediaIntegrityGateTests { [Fact] public void Gate191_ValidateMediaHeader_Mp4_FtypBox_Audit() { // MP4 컨테이너: 0~3 offset box size, 4~7 offset 'ftyp' var mp4ValidHeader = new byte[] { 0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6F, 0x6D }; Assert.True(MediaIntegrityVerifier.ValidateMediaHeader(mp4ValidHeader, ".mp4")); Assert.True(MediaIntegrityVerifier.ValidateMediaHeader(mp4ValidHeader, "video.m4a")); var invalidHeader = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x41, 0x42, 0x43, 0x44 }; Assert.False(MediaIntegrityVerifier.ValidateMediaHeader(invalidHeader, ".mp4")); } [Fact] public void Gate192_ValidateMediaHeader_Webm_Ebml_Audit() { // WebM / MKV EBML Header: 0x1A, 0x45, 0xDF, 0xA3 var webmHeader = new byte[] { 0x1A, 0x45, 0xDF, 0xA3, 0x9F, 0x42, 0x86, 0x81 }; Assert.True(MediaIntegrityVerifier.ValidateMediaHeader(webmHeader, ".webm")); Assert.True(MediaIntegrityVerifier.ValidateMediaHeader(webmHeader, "sample.mkv")); var corruptedHeader = new byte[] { 0x1A, 0x45, 0x00, 0x00 }; Assert.False(MediaIntegrityVerifier.ValidateMediaHeader(corruptedHeader, ".webm")); } [Fact] public void Gate193_ValidateMediaHeader_Mp3_Id3_And_FrameSync_Audit() { // MP3 ID3v2: 'ID3' (0x49, 0x44, 0x33) var id3Header = new byte[] { 0x49, 0x44, 0x33, 0x04, 0x00, 0x00, 0x00, 0x00 }; Assert.True(MediaIntegrityVerifier.ValidateMediaHeader(id3Header, ".mp3")); // MP3 Sync Word: 0xFF, 0xFB var syncHeader = new byte[] { 0xFF, 0xFB, 0x90, 0x64 }; Assert.True(MediaIntegrityVerifier.ValidateMediaHeader(syncHeader, ".mp3")); var badMp3 = new byte[] { 0x00, 0x11, 0x22, 0x33 }; Assert.False(MediaIntegrityVerifier.ValidateMediaHeader(badMp3, ".mp3")); } [Fact] public void Gate194_InspectIntegrity_FullPayload_Audit() { // 유효한 mp4 가짜 데이터 생성 var mp4Data = new byte[64]; mp4Data[4] = 0x66; mp4Data[5] = 0x74; mp4Data[6] = 0x79; mp4Data[7] = 0x70; // ftyp var actualHash = Convert.ToHexString(SHA256.HashData(mp4Data)).ToLowerInvariant(); // 1. 체크섬 일치 및 헤더 유효 var okResult = MediaIntegrityVerifier.InspectIntegrity(mp4Data, "sample.mp4", actualHash); Assert.True(okResult.IsValid); Assert.True(okResult.ChecksumMatch); Assert.Equal("mp4", okResult.Format); Assert.Null(okResult.ErrorReason); // 2. 체크섬 불일치 var mismatchResult = MediaIntegrityVerifier.InspectIntegrity(mp4Data, "sample.mp4", "0000000000000000000000000000000000000000000000000000000000000000"); Assert.False(mismatchResult.IsValid); Assert.False(mismatchResult.ChecksumMatch); Assert.Contains("체크섬", mismatchResult.ErrorReason); // 3. 헤더 손상 var corruptedData = new byte[64]; // all zeros var corruptResult = MediaIntegrityVerifier.InspectIntegrity(corruptedData, "sample.mp4"); Assert.False(corruptResult.IsValid); Assert.Contains("헤더", corruptResult.ErrorReason); } }