KeiStory

zip 파일을 wav 로 변환하고 wav 파일을 다시 zip 파일로 변환하기

 

using System.Security.Cryptography;
using System.Text;

namespace FileWav
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string zipFilePath = "input.zip";
            string wavFilePath = "output.wav";
            string extractedZipFilePath = "extracted.zip";
            string password = "yourpassword"; // 원하는 비밀번호로 변경

            // ZIP 파일을 WAV 파일로 변환
            ConvertZipToWav(zipFilePath, wavFilePath, password);

            // WAV 파일을 ZIP 파일로 복원
            ConvertWavToZip(wavFilePath, extractedZipFilePath, password);
        }


        // ZIP 파일을 암호화하여 WAV 파일로 변환
        public static void ConvertZipToWav(string zipFilePath, string wavFilePath, string password)
        {
            // ZIP 파일을 바이트 배열로 읽기
            byte[] zipData = File.ReadAllBytes(zipFilePath);

            // ZIP 데이터 암호화
            byte[] encryptedData = Encrypt(zipData, password);

            // WAV 파일 생성
            using (FileStream fs = new FileStream(wavFilePath, FileMode.Create))
            using (BinaryWriter writer = new BinaryWriter(fs))
            {
                // RIFF 헤더 작성
                writer.Write(Encoding.ASCII.GetBytes("RIFF"));
                writer.Write(36 + encryptedData.Length); // 파일 크기
                writer.Write(Encoding.ASCII.GetBytes("WAVE"));

                // fmt 청크 작성
                writer.Write(Encoding.ASCII.GetBytes("fmt "));
                writer.Write(16); // Subchunk1Size
                writer.Write((short)1); // AudioFormat (PCM)
                writer.Write((short)1); // NumChannels
                writer.Write(44100); // SampleRate
                writer.Write(44100 * 1 * 8 / 8); // ByteRate
                writer.Write((short)(1 * 8 / 8)); // BlockAlign
                writer.Write((short)8); // BitsPerSample

                // data 청크 작성
                writer.Write(Encoding.ASCII.GetBytes("data"));
                writer.Write(encryptedData.Length); // Subchunk2Size
                writer.Write(encryptedData);
            }
        }

        // WAV 파일을 복호화하여 ZIP 파일로 변환
        public static void ConvertWavToZip(string wavFilePath, string zipFilePath, string password)
        {
            byte[] wavData = File.ReadAllBytes(wavFilePath);

            using (MemoryStream ms = new MemoryStream(wavData))
            using (BinaryReader reader = new BinaryReader(ms))
            {
                // RIFF 헤더 읽기
                string chunkID = new string(reader.ReadChars(4));
                if (chunkID != "RIFF")
                {
                    throw new Exception("유효한 WAV 파일이 아닙니다.");
                }
                reader.ReadInt32(); // 파일 크기
                string riffType = new string(reader.ReadChars(4));
                if (riffType != "WAVE")
                {
                    throw new Exception("유효한 WAV 파일이 아닙니다.");
                }

                // 청크 읽기
                while (reader.BaseStream.Position < reader.BaseStream.Length)
                {
                    string chunkType = new string(reader.ReadChars(4));
                    int chunkSize = reader.ReadInt32();

                    if (chunkType == "fmt ")
                    {
                        reader.ReadBytes(chunkSize); // fmt 청크 건너뛰기
                    }
                    else if (chunkType == "data")
                    {
                        // data 청크에서 암호화된 데이터 읽기
                        byte[] encryptedData = reader.ReadBytes(chunkSize);

                        // 데이터 복호화
                        byte[] zipData = Decrypt(encryptedData, password);

                        // ZIP 파일로 저장
                        File.WriteAllBytes(zipFilePath, zipData);
                        break;
                    }
                    else
                    {
                        reader.ReadBytes(chunkSize); // 기타 청크 건너뛰기
                    }
                }
            }
        }

        // 데이터 암호화 메서드
        private static byte[] Encrypt(byte[] data, string password)
        {
            // 랜덤 솔트 생성
            byte[] salt = GenerateSalt();
            using (Rfc2898DeriveBytes keyGen = new Rfc2898DeriveBytes(password, salt, 10000))
            {
                byte[] key = keyGen.GetBytes(32); // 256비트 키
                byte[] iv = keyGen.GetBytes(16);  // 128비트 IV

                using (Aes aesAlg = Aes.Create())
                {
                    aesAlg.Key = key;
                    aesAlg.IV = iv;

                    using (MemoryStream msEncrypt = new MemoryStream())
                    {
                        // 솔트를 암호화 데이터의 시작에 저장
                        msEncrypt.Write(salt, 0, salt.Length);

                        using (CryptoStream csEncrypt =
                            new CryptoStream(msEncrypt, aesAlg.CreateEncryptor(), CryptoStreamMode.Write))
                        {
                            csEncrypt.Write(data, 0, data.Length);
                        }
                        return msEncrypt.ToArray();
                    }
                }
            }
        }

        // 데이터 복호화 메서드
        private static byte[] Decrypt(byte[] data, string password)
        {
            // 솔트 추출
            byte[] salt = new byte[16];
            Array.Copy(data, 0, salt, 0, 16);

            using (Rfc2898DeriveBytes keyGen = new Rfc2898DeriveBytes(password, salt, 10000))
            {
                byte[] key = keyGen.GetBytes(32); // 256비트 키
                byte[] iv = keyGen.GetBytes(16);  // 128비트 IV

                using (Aes aesAlg = Aes.Create())
                {
                    aesAlg.Key = key;
                    aesAlg.IV = iv;

                    using (MemoryStream msDecrypt = new MemoryStream())
                    {
                        using (CryptoStream csDecrypt =
                            new CryptoStream(msDecrypt, aesAlg.CreateDecryptor(), CryptoStreamMode.Write))
                        {
                            csDecrypt.Write(data, 16, data.Length - 16); // 솔트 부분 제외
                        }
                        return msDecrypt.ToArray();
                    }
                }
            }
        }

        // 솔트 생성 메서드
        private static byte[] GenerateSalt()
        {
            byte[] salt = new byte[16]; // 128비트 솔트
            using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
            {
                rng.GetBytes(salt);
            }
            return salt;
        }
    }
}

결과

 

wav 파일을 재생하면 칙! 소리 내고 바로 끝납니다.

zip 파일을 암호화해서 보내고 싶을 때 사용하면 좋을 듯합니다.

반응형

공유하기

facebook twitter kakaoTalk kakaostory naver band