МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ

advertisement
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
Федеральное государственное бюджетное образовательное учреждение высшего
профессионального образования
«КУБАНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ»
(ФГБОУ ВПО «КубГУ»)
Кафедра вычислительных технологий
КУРСОВАЯ РАБОТА
«Стеганографические методы скрытия данных в аудиосигналах»
Работу выполнила _____________________________________Ю. С. Фисун
(подпись и дата)
Факультет компьютерных технологий и прикладной математики, курс 3
Направление 010300.62 «Фундаментальные информатика и информационные
технологии»
Научный руководитель,
д.ф.-м.н., профессор ____________________________________А.И. Миков
(подпись и дата)
Нормоконтролер
к. ф.-м.н., доцент______________________________________ Е.А. Данилов
(подпись и дата)
Краснодар 2014
1
СОДЕРЖАНИЕ
Введение ……..…………………………………………………………… 3
1. Постановка задачи ……………………………………………………….
5
2. Формат WAV файла ……………………………………………………..
6
2.1. RIFF заголовок ………………………………………………………. 7
2.2. WAV заголовок и его структура …………………………………… 8
2.3. Заголовок данных ……………………………………………………. 9
2.4. Звуковые данные ………………………………………………......... 10
3. Алгоритм сохранения информации в стегоконтейнере ………………. 11
3.1. Алгоритм шифрования информации в стегоконтейнер ………….
11
3.2. Алгоритм дешифрования информации из стегоконтейнера …….
11
3.3. Ограничение на использование данного алгоритма ……………..
12
4. Программная реализация ………………………………………………..
13
5. Результаты работы программы …………………………………………
15
6. Оценка устойчивости разработанного алгоритма к стегоанализу …… 16
Заключение ……………………………………………………………….. 19
Список использованной литературы ………………………………….... 20
Приложение А. Программный код ……..………………………………
21
Приложение Б. Результаты ……………………………………………… 26
2
3
ВВЕДЕНИЕ
Стеганография - это наука о скрытой передаче информации путём
сохранения в тайне самого факта передачи. Слово «стеганография» происходит
от греческих слов «steganos» (секрет, тайна) и «graphy» (запись) и, таким
образом, буквально означает «тайнопись», хотя методы стеганографии
появились,
вероятно,
раньше,
чем
появилась
сама
письменность
(первоначально использовались условные знаки и обозначения).
Как
известно,
цель
криптографии
состоит
в
блокировании
несанкционированного доступа к информации путем шифрования содержания
секретных сообщений. Стеганография имеет другую задачу, и ее цель – скрыть
сам факт существования секретного сообщения. При этом оба способа могут
быть объединены и использованы для повышения эффективности защиты
информации (например, для передачи криптографических ключей).
За
последние
годы
компьютерная
стеганография
окончательно
превратилась из технического искусства в научную область исследования и
приобрела статус самостоятельной прикладной науки, изучающей способы и
методы
сокрытия
секретных
сообщений,
а
также
методы
раскрытия
стеганографических систем.
Особое
аудиосреде.
развитие
Скрытие
перспективным,
сверхшироком
получили
данных
поскольку
динамическом
цифровые
в
методы
аудиосигналах
слуховая
система
диапазоне.
стеганографии
является
человека
Слуховая
особенно
работает
система
в
в
человека
воспринимает более чем миллиард к одному в диапазоне мощности и более чем
тысяча к одному в частотном диапазоне. Кроме этого, высокой является и
чувствительность
к
аддитивному
флуктуационному
(белому)
шуму.
Отклонения в звуковом файле могут быть выявлены вплоть до одной
десятимиллионной (70 дБ ниже уровня внешних шумов).
Несмотря на это, существуют определенные возможности для скрытия
информации и в аудиосреде. Хотя слуховая система человека и имеет широкий
диапазон, она характеризуется достаточно малым разностным диапазоном. Как
4
следствие, громкие звуки содействуют маскировки тихих звуков. Кроме того,
слуховая система человека не способна различать абсолютную фазу,
распознавая только относительную.
Подобные особенности слухового аппарата человека позволяют удачно
использовать
аудиосреду
с
целью
стеганографической
защиты
конфиденциальной информации.
В
рамках
настоящей
курсовой
работы
разработан
алгоритм
преобразования секретной информации, сохраняемой в младших битах, не
нарушая соответствующие закономерности (т.е. устойчивый к стегоанализу).
Приведены результаты работы алгоритма.
Алгоритм реализован в виде программы на C++ для персонального
компьютера.
5
1.
Постановка задачи
Метод сокрытия информации в наименьших значащих битах широко
известен и применяется в большом количестве программных продуктов.
Достоинство
этого
метода
–
высокий
коэффициент
использования
стегоконтейнера.
Самым простым и часто используемым аудио форматом является Waveform Audio (Wave, Wav), который разработан корпорациями Microsoft и
IBM для хранения несжатой, цифровой звуковой информации. Все данные
хранятся в виде 8-ми битовых чисел, расположенных так, чтобы младшая часть
данных записывается первой. В заголовочной части извлекаются основные
параметры — число каналов, битрейт, число фреймов — на основании которых
осуществляется разбор аудиопотока. Wav-файл хранит в себе 1 или 2 канала,
каждый из которых кодируется 8, 16, 24 или 32 битами. Последовательность
бит, описывающая амплитуду волны в момент времени, называется семплом.
Последовательность семплов для всех каналов в определенный момент
называется фреймом.
Программный код, рассмотренный нами в приложении А, заключается в
том, чтобы распознать область, в которую можно производить запись,
пропустив при этом RIFF заголовок, WAV заголовок,
заголовок данных и
перейти к звуковым данным. Программа также должна записать файлсообщение нулями и единицами, и она размещает эти биты поверх самых
младших - восьмых битов каждого семпла в звуковом файле. Если ноль или
единица файла-сообщения волею случая совпадают с нулём или единицей
файла-контейнера, то никаких изменений не происходит. Если же они не
совпадают, программа-стеганограф спокойно записывает последний бит так,
как ей нужно.
Возьмем произвольный текст в кодировке windows-1251 и зашифруем его
в Wav-файл и извлечем его обратно без искажений. Если заменять Байт звука
Байтом
текста,
то
мы
получим
очень
6
сильное
искажение
звука.
Поэтому наиболее удобно заменять только 1 бит каждого семпла на 1 бит
Текста. Такая подмена будет незаметна для слуховой системы человека.
7
2.
Формат WAV файла
Waveform Audio (Wave, Wav) – является самым простым и часто
используемым форматом, который разработан корпорациями Microsoft и IBM
для хранения несжатой, цифровой звуковой информации. При дальнейшей
обработке из 8-ми битных или 16-ти битных данных Wave-формата,
формируются другие форматы звука, которые в большинстве случаев являются
– сжатыми форматами звука – ADPCM, MP3, OGG и другие.
Использование формата WAV является общепринятым, благодаря его
простоте и простой структуре, которая в большой степени основана на формате
файлов RIFF. Благодаря этому, формат WAV не испытывает притеснения среди
различного
программного
обеспечения
или
аппаратных
плееров,
он
поддерживает практически везде.
Формат WAV сохраняет звук в своем изначальном виде без сжатия и
потерь. Именно поэтому WAV-файлы отличаются впечатляющим качеством
звука и зачастую используются на радиостанциях. Например, Радио BBC (BBC
Radio) в Соединенном Королевстве использует 44.1 кГц, 16 бит, стерео - аудио
данные как стандарт в их системе VCS, система ABC “D-Cart”, которая
разработана Австралийским радиовещателем, использует 48 кГц, 16 бит, стерео
- аудио данные, что идентично цифровым аудио кассетам (DAT).
Ниже рассмотрим структуру Wav-файлов. При этом нужно учитывать,
что все данные хранятся в виде 8-ми битовых чисел, расположенных так, чтобы
младшая часть данных записывается первой.
Структура WAV-файла состоит из следующих частей:

RIFF заголовок;

WAV заголовок и его структура;

Заголовок данных;

Звуковые данные;
8
Таблица 1 - Структура WAV-файла.
Смещение от
начала файла
0h
4h
Длина
4h
4h
8h
4h
0ch
4h
10h
14h
16h
18h
4h
2h
2h
2h/4h
1ah/1ch
2h/4h
1ch/20h
2h
1eh/22h
20h/24h
24h/28h
28h/2ch
2h
4h
4h
2.1.
Описание
Идентификатор формата ('RIFF')
Длина блока данных (длина файла - 8h)
Идентификатор блока звуковых данных
('WAVE')
Идентификатор подблока заголовка ('fmt" с пробелом в конце)
000ch/0010h - длина подблока заголовка
01h - тип формата представления данных
Число каналов (1 - моно, 2 - стерео)
Частота дискретизации, Гц
Скорость передачи данных, байт/с
(произведение числа каналов, частоты
дискретизации и разрядности в байтах)
Число байт для представления одного
отсчета (1 - 8 бит моно, 1 - 16 бит стерео)
Разрядность, бит (8, 16)
Идентификатор подблока данных ('data')
Длина звуковых данных
Звуковые данные
RIFF заголовок
Вначале идет заголовок RIFF файла. Он описан следующим образом:
typedef struct {
byte id[4];
long len;
} IDRiff;
id - идентификатор файла = "RIFF" = 0x46464952;
len - длина файла без этого заголовка.
Область данных имеет переменную длину, однако она должна быть
выравнена на границу слова и при необходимости дополнена в конце нулевым
байтом до целого числа слов.
9
Заметим, что формат RIFF не описывает формат данных. Практически
файл в формате RIFF может содержать любые данные для мультимедиа,
причем формат данных зависит от типа данных.
2.2.
WAV заголовок и его структура
Затем идет структура WAV заголовока:
typedef struct {
byte id[4];
byte fmt[4];
long len;
} IDChuckWave;
id - идентификатор = "WAVE" = 0x45564157;
fmt - идентификатор = "fmt " = 0x20746D66;
len - длина куска WAV – файла.
Далее описывается структура WAVEFORMAT:
typedef struct waveformat_tag {
word wFormatTag;
word nChannels;
dword nSamplesPerSec;
dword nAvgBytesPerSec;
word nBlockAlign;
} WAVEFORMAT;
wFormatTag - описывает тип формата звуковых данных;
nChannels - содержит количество каналов. В нем могут находиться
значение 1 (моно) или 2 (стерео);
nSamplesPerSec - записана частота дискретизации, то есть количество
выборок сигнала в секунду. В этом поле могут находиться стандартные
значения (11025 кГц, 22 050 кГц или 44100 кГц) либо нестандартные значения,
такие, как 5000 кГц или 4400 кГц;
10
nAvgBytesPerSec - содержит среднюю скорость потока данных, то есть
количество байт в секунду, передаваемых драйверу устройства или получаемых
от него. Эта информация может быть использована приложением для оценки
размера буфера, необходимого для размещения звуковых данных. Для
монофонического сигнала с дискретностью 8 бит численное значение скорости
совпадает со значением частоты дискретизации. Для стереофонического
сигнала с дискретностью 8 бит она в два раза выше. Точное значение можно
подсчитать по формуле:
nAvgBytesPerSec = (nChannels * nSamplesPerSec * wBitsPerSanipIe) / 8;
nBlockAlign
находится
выравнивание
блока
в
байтах,
которое
подсчитывается по формуле:
nBlockAlign = (nChannels * wBitsPerSample) / 8;
Поле wBitsPerSainple находится в структуре PCMWAVEFORMAT и
содержит дискретность сигнала, то есть количество бит, используемых для
представления одной выборки сигнала. Обычно используются значение 8 или
16.
2.3.
Заголовок данных
Выглядит в следующем формате:
typedef struct {
byte id[4];
long len;
} IDSampleWave;
id - идентификатор ="data" =0x61746164;
len - длина выборки (кратно 2).
11
2.4.
Звуковые данные
Далее идут сами данные звукового файла. Если файл 2-х канальный, то
данные идут по очереди, 1 канал, 2-ой, 1-ый, 2-ой... и т.д. Необходимо также
помнить, что если файл 8 битный, то под каждый сэмпл отводится по одному
байту, если же 16 битный - то по 2 байта. В конце файла иногда бывает
некоторая дополнительная информация о WAV файле (имя Автора и т.д.).
12
3. Алгоритмы шифрования и дешифрования информации в стегоконтейнере
3.1. Алгоритм шифрования информации в стегоконтейнере
1. Загружаем WAV-файл.
2. Определяется позиция начала звуковых данных.
3. Определяется количество семплов.
4. Определяем количество байтов в Исходном Тексте.
5. В первые сорок семплов запишем количество символов Исходного
Текста.
6. Определяем позицию смещения для записи в биты.
7. Организовываем два цикла:
- Внешний: обход по битам семплов;
- Внутренний: обход по битам символа.
8. В циклах заменяем последний бит семпла инверсией бита текста
последовательно (т.е. если бит текста равен 1, то в бит семпла записываем 0).
Пропуская при этом последние биты семплов, которые попали под область
смещения.
9. Сохраняем полученный результат.
3.2. Алгоритм дешифрования информации из стегоконтейнера
1. Загружаем WAV-файл.
2. Определяется позицию начала звуковых данных.
3. Из первых сорок семплов считываем последние биты, преобразовав
их, получаем количество символов Исходного Текста.
4. Определяем позицию смещения для считывания нужных битов
семплов.
5. Организуем цикл обхода по битам семплов, учитывая при этом
смещение. Количество итераций в цикле равно количеству символов
умноженное на восемь.
6. Применяем инверсию к полученным последним битам.
7. Сохраняем полученный результат.
13
3.3. Ограничение на использование данного алгоритма
1. Сообщение не должно превосходить размер WAV-файла.
2. В сообщении должны использоваться только символы кириллицы,
латиницы, а также цифры от 0 до 9.
3. Контейнер не имеет сжатия.
4. В контейнере должно выделяться 8 бит на семпел.
14
4. Программная реализация
Программный код написан на языке С++. В программе используется
структура Wav-файла, описанная выше:
struct WAVHEADER
{
byte chunkId[4];//Содержит символы "RIFF" в ASCII кодировке
unsigned long chunkSize; //это размер файла
byte format[4];// Содержит символы "WAVE"
byte subchunk1Id[4]; // Содержит символы "fmt "
unsigned long subchunk1Size;// размер подцепочки
unsigned short audioFormat;// Формат сжатия
unsigned short numChannels;// Количество каналов
unsigned long sampleRate; // Частота дискретизации
unsigned long byteRate;
unsigned short blockAlign;// Количество байт для одного семпла
unsigned short bitsPerSample;// Точность звучания
byte subchunk2Id[4];// Содержит символы "data"
unsigned long subchunk2Size;// Количество байт в области данных.
// Далее следуют непосредственно Wav-данные.
};
Используются следующие функции:

ByteToBinary- разбивает исходный Байт на биты. Возвращает
массив из восьми элементов. Каждый N-й элемент соответствует N-му биту.
Принимает значения 1 или 0;

Power – функция, возводит в степень значения

CheckWavFile - функция проверяет, подходит ли исходный файл
для работы над ним программы;

Inversion – функция инвертирует биты, т.е. 1->0, а 0->1
15

GetBitValue - Получает значение N-ого бита в байте B. Возвращает
1 или 0 (в зависимости от значения Бита). Функция используется в функции
ReadBitToByte;

BinaryToByte- Собирает из массива битов один целый байт и
возвращает его;

ReadBitToByte - Записывает в байт B на последнюю позицию бит

Mass- преобразовывает десятиричное число в двоичную систему
Bit;
счисления и на выходе получаем массив;

QuantitySymbol – преобразовывает двоичное число в десятеричную
систему счисления;
В программе также содержится две основные функция для шифрования
текста в звуковой файл encrypt() и функция для извлечения текста из звукового
файла decrypt().
Программный код представлен в Приложении А.
Результаты работы программы представлены в ПРИЛОЖЕНИИ Б.
16
5. Результаты работы программы
Искажения, вносимые методом замены наименьшего значащего бита в
реальном звуковом сигнале, можно визуально обнаружить путем анализа
спектра сигнала. Проверка слышимости искажений (другими словами,
возможности обнаружения вложений) была проведена визуально с помощью
звукового редактора Audacity 1.3.
В качестве контейнера использовался звуковой файл, который содержал
запись инструментального симфонического произведения. В ПРИЛОЖЕНИИ Б
на рисунке 1 изображен спектр пустого контейнера, а на рисунке 2 изображен
спектр с заменой последнего младшего бита. Для сравнения на рисунке 3
представлен спектр с заменой 4-го бита и на рисунке 4 спектр с заменой 6-го
бит.
Внедрение в самые младшие разряды не вносило заметных искажений.
Изменения в средних битах надежно выявлялись путем анализа спектра, но
плохо различались на слух. При внедрении информации в старшие биты
искажения были различимыми даже на слух. Наиболее заметные искажения
обнаруживались на участках с низким уровнем звукового сигнала («полная
тишина»). Если исключить внедрение информации на участках с низким
уровнем громкости, то для внедрения можно использовать последние два бита.
При этом изменения спектра с помощью звукового редактора Audacity 1.3
визуально зарегистрировать нельзя.
17
6.
Устойчивость разработанного алгоритма к стегоанализу
Стегоанализ – сравнительно новое направление исследований в сфере
стеганографии. Стегоанализом, по аналогии с криптоанализом,
называется
задача, обратная по отношению к стеганографии, и заключается в обнаружении
подозрительного контейнера, в который каким-либо методом могли быть
включена посторонняя информация, с намерением скрыть сам факт ее
нахождения.
Данные,
которые
вносятся
в
контейнер,
могут
быть
предварительно зашифрованы, чтобы усложнить задачу стегоаналитика, однако
основная цель, стоящая перед ним – не извлечь информацию и прочитать, а по
крайней мере, обнаружить скрытый канал передачи данных.
Известно, что файлы аудио форматов могут служить хорошим
контейнером для стеганографической передачи данных, так как обладают
необходимой
информационной
избыточностью.
Одним
из
широко
используемых методов стеганографии для аудио-файлов является перезапись
его младших бит. Визуально звуковой файл при этом не изменяется, особенно
если в качестве контейнера выбран звуковой файл с низкочастотным шумом, то
есть информационно нагруженное. Это в значительной степени осложняет
работу стегоаналитика, если он не обладает специальными средствами
стегоанализа.
Метод звукового анализа является самым простым способом анализа
звуковых файлов, поскольку для этого достаточно просто прослушать аудиофайл. Тем не менее, этот метод анализа уже способен установить некоторые
ограничения на объем скрываемых данных. Так, для аудиосигналов в формате
WAV незаметными для человеческого слуха будут искажения менее 10%. Если
в результате скрытия в аудиосигналах возникают незначительные искажения,
то их можно объяснить применением процедуры сжатия.
Один из известных методов стегоанализа - метод визуального анализа
битовых срезов. Основная идея метода заключается в сравнении исходного
звукового файла в целом с его битовыми срезами.
18
Для метода визуального анализа битовых срезов большое значение имеет
то, как именно осуществляется запись скрываемой информации. Если она
записывается в подряд идущие биты, то факт скрытия сообщения может быть
установлен с большой вероятностью. Но если распределить скрываемую
информацию по всему контейнеру, то факт скрытия может быть установлен с
малой вероятностью.
Одним из оригинальных методов статистического стегоанализа является
метод RS, впервые опубликованным в 2001 г. коллективом ученых под
руководством Дж. Фридрих. Сокращение в названии расшифровывается
как Regular-Singular, то есть «регулярно-сингулярный».
Суть метода состоит в следующем. Весь звуковой файл разбивается на
группы по n семплов G(x1,x2,…,xn), где n четно, например по 2 семплов,
находящихся рядом. Для группы семплов определяется функция регулярности
или «гладкости» f(G), в качестве такой функции можно выбрать, например,
дисперсию значений внутри группы, либо просто сумму перепадов значений
смежных семплов. Под значением семпла понимаем целое число от 0 до 255.
𝑛−1
𝑓(𝑥1 , 𝑥2 , … , 𝑥𝑛 ) = ∑ |𝑥𝑖+1 − 𝑥𝑖 |
(1)
𝑖=1
Функция F(x) называется флиппингом и имеет свойство F(F(x)) = x.
Определим две функции флиппинга – F1, соответствует инверсии младшего
бита семпла, и F2, представляющая собой инверсию с переносом в старший бит
(прибавление единицы).
F1: 0 ↔ 1, 2 ↔ 3, …, 254 ↔ 255
F-1: 255 ↔ 0, 1 ↔ 2, 3 ↔ 4, …,253 ↔ 254, 255 ↔ 0
При применении флиппинга к группе получаем преобразованную группу
пикселов. Далее, поделим все группы семплов на классы следующим образом:
-
Регулярные группы: G ∈ R ⇔ f(F(G)) > f(G)
-
Сингулярные группы: G ∈ S ⇔ f(F(G)) < f(G)
-
Неиспользуемые группы: G ∈ U ⇔ f(F(G)) = f(G)
19
В дальнейшем нас будет интересовать соотношение между группами в
Wav-файле. Определим количество групп попавших в тот или иной класс как
RM, SM, UM и R-M, S-M, U-M, где индексы M и - М означают соответственно
применение F1 и F-1 для получения распределения. Наша цель – определить
каким образом внедрение сообщения методом LSB будет влиять на
вышеописанную статистику групп семплов.
Метод основывается на статистическом предположении, что для
естественного аудиосигнала, другими словами, незаполненного контейнера,
характерно следующее:
RM ≅ R−M и SM ≅ S−M
(2)
Предположение основано на том, что применение F -1 даст то же
распределение, что и F1 на аудио-файле, значения семплов которого сдвинуты
на единицу. Для обыкновенного аудио-файла соотношение между группами не
должно существенно меняться. Значительное расхождение между значениями
свидетельствует о применении LSB-стеганографии для младших бит аудиофайла.
Рассмотрим изменения младших бит аудио-файла при 100% перезаписи
их битами сообщения. Внедрение случайного сообщения длиной, равной
размеру изображения, приведет к тому, что 50% младших бит, будут
инвертированы. Это, в свою очередь сведет к нулю разность между
значениями RM и SM. Однако на R-M и S-M внедрение сообщения будет влиять
прямо противоположно, и разность этих величин будет пропорциональна
степени заполненности контейнера, иными словами длине сообщения.
20
ЗАКЛЮЧЕНИЕ
В рамках настоящей курсовой работы предложен алгоритм, реализующий
метод замены наименее значащих битов для файлов с расширением WAV. Была
изучена предметная область, сформулирована постановка задачи, рассмотрен
формат WAV файла, проанализирован метод наименее значимого бита для
звуковых файлов. На основе анализа закономерностей изменения младших
битов
разработан
алгоритм
преобразования
секретной
информации,
сохраняемой в младших битах.
С помощью программной среды Microsoft Visual Studio 2010 C++ был
реализован рассмотренный алгоритм. Получены звуковые файлы,
отображающие полученные преобразования.
Метод замены наименее значащих бит небольшой сложности, тем не
менее, способен сохранить в тайне факт передачи информации, позволяет
передавать достаточно большие сообщения.
Сама стеганография сейчас занимает свою нишу в обеспечении
безопасности: она не заменяет, а дополняет криптографию. Сокрытие
сообщения методами стеганографии значительно снижает вероятность
обнаружения самого факта передачи сообщения. А если это сообщение к тому
же зашифровано, то оно имеет еще один, дополнительный, уровень защиты.
Также очень перспективно использование стеганографии в тех странах, где
существуют законы, ограничивающие применение криптографии, как еще
одного способа ограничить доступ к файлам.
21
СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ
1. Грибунин В.Г., Оков И. Н., Туринцев И.В. Цифровая стеганография. – М.:
Солон-Пресс, 2002. – 272 с.
2. Конахович Г. Ф., Пузыренко А. Ю. Компьютерная стеганография. Теория
и практика. — К.: МК-Пресс, 2006. — 288 с, ил.
3. Фролов А.В, Фролов Г.В. Мультимедиа для Windows. – М.: Издательство
Диалог-МИФИ, 1995 г.- 336 с.: ил.
4. И. А. Алдошина, Э. И. Вологдин, А. П. Ефимов и др. Электроакустика и
звуковое вещание: Учебное пособие для вузов. М.: Горячая линия –
Телеком, Радио и связь, 2007. – 872 с.
22
ПРИЛОЖЕНИЕ А. ПРОГРАММНЫЙ КОД
#include
#include
#include
#include
#include
#include
#include
#include
#include
<iostream>
<fstream>
<stdio.h>
<tbyte.h>
<Windows.h>
<conio.h>
<string.h>
<ctime>
<cstdlib>
using namespace std;
struct WAVHEADER// Структура, описывающая заголовок WAV файла.
{
byte chunkId[4];//Содержит символы "RIFF" в ASCII кодировке
unsigned long chunkSize; //это размер файла
byte format[4];// Содержит символы "WAVE"
byte subchunk1Id[4]; // Содержит символы "fmt "
unsigned long subchunk1Size;// Это оставшийся размер подцепочки, начиная с этой позиции.
unsigned short audioFormat;// Формат сжатия.Значения, отличающиеся от 1, обозначают
некоторый формат сжатия.
unsigned short numChannels;// Количество каналов. Моно = 1, Стерео = 2 и т.д.
unsigned long sampleRate; // Частота дискретизации. 8000 Гц, 44100 Гц и т.д.
unsigned long byteRate;// sampleRate * numChannels * bitsPerSample/8
unsigned short blockAlign;// Количество байт для одного семпла, включая все каналы.
unsigned short bitsPerSample;// Так называемая "глубиная" или точность звучания. 8 бит,
16 бит и т.д.
byte subchunk2Id[4];// Содержит символы "data"
unsigned long subchunk2Size;// Количество байт в области данных.
// Далее следуют непосредственно Wav данные.
};
int power(int pow,int val)//функция вычисляет число val в степени pow
{
int value=1;
for(int i=0;i<pow;i++)
value*=val;
return value;
}
bool CheckWavFile(WAVHEADER header)//функция проверяет является ли файл wav-файлом и
подходит ли он нам для работы
{
bool flag=true;
if ((header.chunkId[0] != 'R')&&(header.chunkId[1] != 'I')&&(header.chunkId[2] !=
'F')&&(header.chunkId[3] != 'F')) //Если RIFF не получили, то значит какую то залепу открыли
{
cout<<"File has no RIFF - formated"<<endl;
flag=false;
}
if ((header.format[0] != 'W')&&(header.format[1] != 'A')&&(header.format[2] !=
'V')&&(header.format[3] != 'E')) //Проверим
{
cout<<"File has no section WAVE"<<endl;
flag=false;
}
if ((header.subchunk1Id[0] != 'f')&&(header.subchunk1Id[1] !=
'm')&&(header.subchunk1Id[2] != 't')&&(header.subchunk1Id[3] != ' ')) //Если секция fmt - не
найдена
{
cout<<"File has no section Format(fmt) "<<endl;
23
flag=false;
}
if (header.audioFormat != 1) //Если таг <>1 то значит есть компрессия файла, ее
разбирать мы не будем, работаем не с жатыми данными
{
cout<<"File has a compression"<<endl;
flag=false;
}
if ((header.subchunk2Id[0] != 'd')&&(header.subchunk2Id[1] !=
'a')&&(header.subchunk2Id[2] != 't')&&(header.subchunk2Id[3] != 'a')) //Ну а теперь сама
data - это то, над чем мы будем работать
{
cout<<"File has no section data"<<endl;
flag=false;
}
return flag;
}
int *ByteToBinary (byte val)// Разбивает исходный Байт на биты. Возвращает массив из восьми
элементов.Каждый Nй элемент соответствует Nму биту.
{
int *mass = new int[8];
int t, i;
for (t = 128, i = 0; t > 0; t /= 2, i++)
{
if ((val & t) != 0) mass[i] = 1;
else if ((val & t) == 0) mass[i] = 0;
}
return mass;
}
int GetBitValue(byte B)// Получает последнего бита в байте B.Возвращает 1 или 0 (в
зависимости от значения Бита)
{
int k = 256;
for (int i = 0; i < 8; i++) k /= 2;
if ((B & k) != 0) return 1;
else return 0;
}
int Inversion(int B)
{
if(B==0) return 1;
else return 0;
}
byte BinaryToByte (int *mass)//Собирает из массива битов один целый байт и возвращает его.
{
byte Mask
= 00000001;
byte Result = 00000000;
byte Mask2;
int j = 0;
for (int i = 7; i > -1; i--, j++)
{
if (mass[i] == 1)
{
Mask2 = (Mask << (j));
Result = Result|Mask2;
}
}
return Result;
}
byte ReadBitToByte (int Bit, byte B)//Записывает в байт B на последнюю позицию бит Bit
24
{
byte A = 00000001;
byte Result = B;
if (Bit == GetBitValue(B))
return B;
else if (Bit == 1)
return Result = Result|A;
else if (Bit == 0)
return B - A;
return NULL;
}
int *mass(int val)//преобразовывает десятиричное число в двоичную систему счисления и на
выходе получаем массив из 40 символов
{
int j=40;
int *mas = new int[40];
for (int i=0;i<40;++i) mas[i]=0;
while(val>=1)
{
if(val!=1)
{
if(val/2==1)
{
mas[j]=1;
}
else
{
mas[j]=0;
}
val=val%2;
}
else
{
mas[j]=1;
}
--j;
}
return mas;
}
int QuantitySymbol(int *massiv)//перевод из двоичной системы счисления в десятиричную
{
int k=0;
for(int i=0;i<40;++i)
{
k=k+massiv[40-i]*power(i,2);
}
return k;
}
int encrypt()
{
FILE *file,*file1;//для связывания файлов
int quantity_sym=0;//количество символов
bool flag=false;
int num_sym=0;//номер символа
byte pAudio; //переменная для звуковых данных
byte *pData = new byte; //Динамически выделим переменную типа byte- текстовых данных
int *mas=new int;
byte newAudio;//переменная для новых аудио данных
int dislocation;//смещение для записи новых бит
errno_t err;
err = fopen_s(&file, "Sound.wav", "rb");
25
fopen_s(&file1, "SoundOut.wav", "rb");
if (err)
{
cout<<"Failed open file
return 0;
"<< err <<endl;//ошибка,если не удалось открыть
}
WAVHEADER header;
fread_s(&header, sizeof(WAVHEADER), sizeof(WAVHEADER), 1, file);
fwrite(&header, sizeof(WAVHEADER), sizeof(WAVHEADER), file1);//копируем нашу
структуру в выходной файл
fclose(file);
fclose(file1);
if(!CheckWavFile(header)) return 0;
ofstream audioOut("SoundOut.wav",ios::app |ios::hex);
ifstream text("text.txt",ios::beg | ios::in|ios::hex);//
while(!text.eof())
{
text>>pData[quantity_sym];
quantity_sym++;
}
ifstream audio("Sound.wav",ios::beg | ios::in|ios::hex);//
audio.ignore(28);
dislocation=header.subchunk2Size-40/quantity_sym*8;//определяем позицию смещения
if(quantity_sym>(header.subchunk2Size-40)*8)
{
cout<<"Not enough space"<<endl;
return 0;
}
mas=mass(quantity_sym);
while(!audio.eof())
{
audio>>pAudio;
if(!flag)
{
flag=true;
for(int f=0;f<40;f++)//количество символов в тексте записываем в первые
40 семплов
{
newAudio=pAudio;
ReadBitToByte (mas[f], newAudio);//Записывает в байт B на
последнюю позицию бит Bit
audioOut<<newAudio;
audio>>pAudio;
}
}
int massiv=*ByteToBinary(pData[num_sym]);//получили массив бит символа
for(int y=0;y<8;y++)
{
newAudio=pAudio;
ReadBitToByte(Inversion(massiv[&y]), newAudio);//записываем в последний
бит семпла биты массива каждого символа
audioOut<<newAudio;
audio>>pAudio;
audio.ignore(dislocation);//в семплах которые вошли в смещение,мы
игнорируем
}
num_sym++;
}
audio.close();
audioOut.close();
return 0;
}
int decrypt()
{
26
FILE *file;
errno_t err;
int quatity_sem=0;//количество семплов
int quantity_sym=0;//количество символов
int *massiv=new int[40];//массив для 40 битов
int num_sym=0,num_sem=0;;//номер символа и семпла
int dislocation;//позиция для смещения
byte symbol;//символ
int *mass=new int[8];//массив для 8 битов последних
byte *pData = new byte;; //Динамически выделим переменную типа byte[размер звуковых
данных]
fopen_s(&file, "SoundOut.wav", "rb");
if (err)
{
cout<<"Failed open file "<< err <<endl;//ошибка,если не удалось открыть
return 0;
}
WAVHEADER header;
fread_s(&header, sizeof(WAVHEADER), sizeof(WAVHEADER), 1, file);
fclose(file);
if(!CheckWavFile(header)) return 0;//проверка на соответствие файла
byte *pAudio = new byte[header.subchunk2Size]; //Динамически выделим переменную типа
byte[размер звуковых данных]
ifstream audio("SoundOut.wav",ios::beg | ios::in|ios::binary);//
audio.ignore(28);
while(!audio.eof())
{
audio>>pAudio[quatity_sem];
quatity_sem++;
}
audio.close(); //Закроем файл, он нам уже не нужен, у нас есть pAudio
ofstream text("TextOut.txt",ios::beg | ios::in|ios::hex);//
for(int f=0;f<40;f++)//количество символов в тексте в 40 семплов
{
massiv[f]=GetBitValue(pAudio[f]);//последний бит считываем
}
quantity_sym=QuantitySymbol(massiv);
dislocation=header.subchunk2Size/quantity_sym*8;//позиция для смещения
while(num_sym<quantity_sym)
{
for(int i=0;i<8;i++)
{
mass[i]=Inversion(GetBitValue(pAudio[num_sem]));
num_sem++;
}
pData[num_sym]=BinaryToByte(mass);
num_sem+=dislocation;
num_sym++;
}
for(int j=0;j<num_sym-1;j+2)
{
symbol=pData[j]+pData[j+1];
text<<symbol;
}
text.close();
return 0;
}
int main()
{
encrypt();
decrypt();
system("pause");
return 0;
}
27
ПРИЛОЖЕНИЕ Б. РЕЗУЛЬТАТЫ
Рисунок 1 – Пустой контейнер.
Рисунок 2 – Контейнер, в котором изменен последний младший бит.
28
Рисунок 3 – Контейнер, в котором изменены средние биты.
Рисунок 4 – Контейнер, в котором изменены старшие биты.
29
Download