Как зашифровать картинку в звук
Аудио-графическое шифрование или как звук в картинку спрятать
Довольно необычный способ потратить два дня в попытках зашифровать аудиофайл в обычное изображение. О методах, возникших проблемах и результатах читайте ниже.
Предыстория
Под покровом вечера пятницы, поглощая хмельные запасы нашей необъятной и листая любимый Хабр, я наткнулся на плеяды статей о шифровании. Что только куда не зашифровывали, от совсем уж банального шифра Цезаря до менее банального шифрования изображений в аудиофайл. Наслаждаясь достойным вечера чтивом, в голову зашел не разувшись интересный вопрос: «-А кто-нибудь звук в картинку прятал?». Зудящая жажда знаний заставила меня смахнуть с живота остатки кальмаровых колец и сесть за свою рабочую лошадку.
К моему великому удивлению не нашел ничего (Либо этим никто на занимался, либо занимался, но с миром делиться не стал, ну либо я плохо искал. Пятница, вечер, сами понимаете). В любом случае маховик моей решительности уже начал раскручиваться. Итак давайте по порядку. ( полный код проекта здесь ). Примеры для затравочки)):
Секундная запись гугл-маруси А вот десятисекундная запись моего простуженного голоса
Метод шифрования
Первым делом я решил продумать саму схему шифрования. Как удобно, экономично и безболезненно можно засунуть звук в изображение? Не буду говорить о всех идеях которые посещали чертоги моего разума, расскажу о методе который я впоследствии и выбрал. Давайте представлю схему для вашего удобства, а потом будут поблочные разъяснения.
Первым делом получаем samplerate(частота дискретизации) и data(значения пиков амплитуды аудиодорожки) с помощью scipy.io.wavfile. В коде на Python это выглядит так:
Теперь второй шаг. Проходимся циклом по списку data и из каждого значения создаём hex-code.Например, из значения 544 получаем #544aaf и так далее. Буквенные значения являются солью(salt) и создаются рандомно. Здесь кстати обнаруживается первая проблема. Значения амплитуды могут принимать отрицательные значения, hex-code же минусы не жалует. Решается просто, заменяем ‘-‘ на ‘f’ и будем обращать внимание на этот флаг при дешифровке. Конечная реализация выглядит так:
В этом же шаге переводим значения hex-code из new_arr в RGB формат. Это и есть цвета пикселей будущего изображения. Не забываем зашифровать значение samplerate в последний пиксель. Далее переводим наш np.array массив в квадратную размерность и создаем из него изображения с помощью Image.fromarray библиотеки PIL(Pillow):
Обернув всё вышеописанное в функцию получаем:
Вот как то так. На выходе получаем изображение, с одной стороны мешанина из пикселей, с другой, что то она мне напоминает(Спектрограмма? Возможно).В любом случае, без функции дешифровки это всего лишь хоть и красивая, но бесполезная пнгэшка. Кстати о дешифровке. План тот же, схема, а потом пояснения с кодом.
Получая на вход изображение с зашифрованным аудио внутри, функция decode() первым делом получает np.array значений RGB этой картинки и вытягивает его в одномерный массив. Далее она проворачивает прямо противоположное функции encode():
Послесловие, итоги, оговорки и ограничения
Мда, получилось конечно здорово. Время потрачено не зря. Но. Давайте о минусах:
Второе. Алгоритм шифровки/дешифровки не самый быстрый, аудио длиной три минуты кодируется минут 15, более того, разрешение выходного изображения также напрямую зависит от длительности аудиофайла. Тот же трёхминутный фрагмент в зашифрованном виде имеет разрешение 3058х3058 пикселей. Не слабо. Но зато потери минимальные! при сравнении оказалось что исходный и дешифрованный файлы идентичны на 99.3%!! Было бы сто, но мадам частота дискретизации не хочет дешифроваться без потерь.
На этом собственно всё. Мне осталось только пожелать вам удачи и свершений и оставить ссылочки))
Превращаем картинку в звук
Попробуем заняться довольно бессмысленным занятием, а именно получением звука с определенной спектрограммой. Вдруг ряды любителей ЭГФ сократятся, не в обиду фанатам фильма «Белый шум» 🙂
Итак, начнем с моделирования на Matlab. Хотим алгоритм, позволяющий переводить звук в картинку-спектрограмму и обратно. Логично будет начать с вычисления спектрограммы, по которой будет вычисляться изображение.
Чтобы не делать того, что уже давно сделано за нас другими, здесь используется функция enframe из библиотеки voicebox,предназначенной для решения разнообразных задач при распознавании речи. Функция enframe как раз и позволяет нарезать сигнал на кадры с заданным шагом. Длину кадра мы берем мы берем равным длине преобразования Фурье(FFTLEN= 256), а шаг — половина этого значения(128). Все в лучших традициях 🙂 На каждый кадр накладывается окно Хэннинга для устранения боковых лепестков при вычислении ДПФ. Так как кадры идут с половинным перекрытием, то при наложении окна, сумма весов под перекрывающимися участками равна 1 и мы легко можем восстановить сигнал в половине кадра по двум соседним кадрам.
Для фразы «Почему не стоит пользоваться аутсорсингом в странах с дешевой рабочей силой» получилась следующая спектрограмма:
Естественно, что однозначно мы восстановить сигнал не сможем. При получении изображения каждый отсчета спектрограммы берется модулем комплексного значения — теряется информация о фазе. Поэтому, если просто собрать восстановленные половинки, то будут две проблемы:
Первая проблема пока остается, для решения второй я пытался подкручивать фазу при сборке полукадров — через один полукадр. Делалось это примерно так:
После восстановления, получилось вот что
И теперь осталось только написать небольшую функцию получения спектрограммы из картинки. Изображение превращаем в черно-белое, а затем масштабируем до нужного размера по высоте.
Немножко сжульничал, строчкой «image = 1-image;» сделав негативное изображение, чтобы наш мишка выглядел яркими пятнами на темном, а не наоборот. Иначе — было бы слишком много шума.
Полученный звук, естественно, для сохранения психического равновесия слушать категорически не рекомендуется… Желающие могут поподбирать картинку, чтобы получить что-нибудь похожее на транс-музыку от Майкрософта.
Исходный код и все необходимое из статьи можно скачать отсюда.
Sound Art — Приложение для конвертации изображений в звуки (x32, x64)
Sound Art — это абсолютно бесплатное приложение для преобразования изображения в звук для Windows. Разработано Василием Макаровым из студии Stone Voices. Он известен нам по работе над виртуальными синтезаторами PolyGAS и Brandulator. На этот раз выпущенное программное обеспечение это не плагин VST, а отдельная компьютерная программа. Её цель — конвертировать картинки в звуки и наоборот.
Так как же работает Sound Art и что она делает? Приложение использует принцип Фурье для анализа любого фото, предоставленного пользователем, и преобразования его в сэмпл. Аналогично, часть звука может преобразовываться в фотографию, подобно любому другому фото на вашем компьютере. Можете сохранить аудиозапись как фотоснимок, обработать в стороннем фоторедакторе, таком как Photoshop, а затем преобразовать его обратно в аудио для прослушивания изменений. Sound Art экспортирует аудиофайлы в формате WAV и изображения PNG, JPEG, BMP или TGA.
Получающиеся в результате звуковые файлы часто звучат как что-то среднее между звуковым пейзажем и записью модема. Иногда из получившегося изображения можно извлечь интересную петлю или ритмическую последовательность. Мы совсем немного протестировали этот софт, прежде чем писать эту статью, но первые впечатления очень положительные. Sound Art можно применить в качестве отправной точки для специальных музыкальных проектов. Попробуйте его как секретный инструмент обработки синтезируемых битов и риффов. Отличная вещь для сумасшедших экспериментов и синтеза нового, необычного аудио материала.
Прячем ценный файл в картинку или аудио
Добрый день всем, кто оказался на данном сайте. Сегодня хотелось бы затронуть тему стеганографии. Вы наверняка не раз видели в фильмах как зашифровывают ценные файлы в изображениях или в аудио файлах. Так вот, этот метод называется ” Стеганография”. Давайте разберемся, как нам так же сделать на нашем компьютере под управлением Linux. А помогут нам в этом деле две небольшие утилиты “Steghide” и “StegoSuite”. В Deb дистрибутивах (Debian, Ubuntu, Kali Linux и так далее) они имеются в официальных репозиториях.
Давайте рассмотрим что может Steghide:
1 – сжатие встроенных данных
2 – шифрование встроенных данных
3 – поддержка файлов JPEG, BMP, WAV и AU
А теперь рассмотрим что может Stegosuite:
1 – Поддержка BMP, GIF и JPG
2 – Шифрование AES встроенных данных
3 – Легко использовать (Графический интерфейс)
Установка Steghide
Теперь рассмотрим как нам спрятать текстовый файл в картинке. Для этого я поместил эти два файла в домашнем каталоге пользователя
После чего открываем этот каталог в терминале и вводим следующую команду
Программа попросит вас дважды ввести пароль root пользователя. По окончанию вы увидите надпись “embedding “secret” in “hacked.jpg”… done”. Это будет означать что операция прошла успешно.
Для того что бы извлечь файл из картинки “hacked.jpg”, нам нужно ввести соответствующую команду
Для наглядности я скопировал файл “hacked.jpg” в директорию “загрузки” и открыл ее в терминале
Проверяем что все у нас получилось командой введенной в терминале
Если вам нужно узнать, содержит ли изображение зашифрованный файл, то введите в терминале команду
Покажу пример все на том же файле, что мы использовали чуть раньше. Удаляю из папки загрузка все содержимое и снова помещаю наш “секретный” файл hacked.jpg в эту папку. После чего ввожу выше указанную команду
Установка StegoSuite
Теперь рассмотрим вторую программу. Она имеет графический интерфейс, но, в отличии от первой нем может скрывать файлы в аудио дорожках. Установка такая же простая, достаточно ввести команду
Найти ее можно в меню пуск
Тут все просто, нажимаете на “File – Open” и выбираете изображение.
Потом щелкаем правой кнопкой мыши в окошке “embedded file” и выбираем второй файл, которой хотим зашифровать в этом изображении.
После чего вводите пароль и нажимаете кнопку “Embed”, при желании можно указать любую запись в самом верхнем окошке
В папке вы увидите уже “объединенный файл”
Что бы извлечь наш “спрятанный” в этой картинке файл, достаточно его открыть в stegosuite, указать пароль в соответственном окошке и нажить “Extract”
Как видите, все достаточно просто. Надеюсь данная инструкция будет вам полезна. Не используйте эту инструкцию в корыстных целях.
Преобразуем изображение в звук — что можно услышать?
В недавней публикации здесь на сайте описывалось устройство, позволяющее незрячим людям «видеть» изображение, преобразуя его с помощью звуковых волн. С технической точки зрения, в той статье не было никаких деталей вообще (а вдруг украдут идею за миллион), но сама концепция показалась интересной. Имея некоторый опыт обработки сигналов, я решил поэкспериментировать самостоятельно.
Что из этого получилось, подробности и примеры файлов под катом.
Преобразуем 2D в 1D
Первая очевидная задача, которая нас ожидает — это преобразовать двухмерное «плоское» изображение в «одномерную» звуковую волну. Как подсказали в комментариях к той статье, для этого удобно воспользоваться кривой Гильберта.
Она по своей сути похожа на фрактал, и идея в том, что при увеличении разрешения изображения, относительное расположение объектов не меняется (если объект был в верхнем левом углу картинки, то он останется там же). Различные размерности кривых Гильберта могут дать нам разные изображения: 32×32 для N=5, 64×64 для N=6, и так далее. «Обходя» изображение по этой кривой, мы получаем линию, одномерный объект.
Следующий вопрос это размер картинки. Интуитивно хочется взять изображение побольше, но тут есть большое «но»: даже картинка 512х512, это 262144 точек. Если преобразовать каждую точку в звуковой импульс, то при частоте дискретизации 44100, мы получим последовательность длиной в целых 6 секунд, а это слишком долго — изображения должны обновляться быстро, например с использованием web-камеры. Делать частоту дискретизации выше бесмысленно, мы получим ультразвуковые частоты, неслышимые ухом (хотя для совы или летучей мыши может и пойдет). В итоге методом научного тыка было выбрано разрешение 128х128, которое даст импульсы длиной 0.37c — с одной стороны, это достаточно быстро чтобы ориентироваться в реальном времени, с другой вполне достаточно, чтобы уловить на слух какие-то изменения в форме сигнала.
Обработка изображения
Первым шагом мы загружаем изображение, преобразуем его в ч/б и масштабируем до нужного размера. Размер изображения зависит от размерности кривой Гильберта.
Следующим шагом формируем звуковую волну. Тут разумеется, может быть великое множество алгоритмов и ноухау, для теста я просто взял яркостную составляющую. Разумеется, наверняка есть способы лучше.
Из кода, надеюсь, все понятно. Функция coordinates_from_distance делает за нас всю работу по преобразованию координат (х, у) в расстояние на кривой Гильберта, значение яркости L мы инвертируем и преобразуем в цвет.
Это еще не все. Т.к. на изображении могут быть большие блоки одного цвета, это может привести к появлению в звуке «dc-компоненты» — длинного ряда отличных от нуля значений, например [100,100,100. ]. Чтобы их убрать, применим к нашему массиву high-pass filter (фильтр Баттерворта) с частотой среза 50Гц (совпадение с частотой сети случайно). Синтез фильтров есть в библиотеке scipy, которым мы и воспользуемся.
Последним шагом сохраним изображение. Т.к. длина одного импульса короткая, мы повторяем его 10 раз, это будет на слух более приближено к реальному повторяющемуся изображению, например с веб-камеры.
Результаты
Вышеприведенный алгоритм, разумеется, совсем примитивный. Я хотел проверить три момента — насколько можно различать разные несложные фигуры, и насколько можно оценить расстояние до фигур.
Изображению соответствует такой звуковой сигнал:
Идея этого теста — сравнить «звучание» объекта другой формы. Звуковой сигнал:
Можно заметить, что звучание действительно другое, и на слух разница есть.
Идея теста — проверить объект меньшего размера. Звуковой сигнал:
В принципе, чем меньше размеры объекта, тем меньше будет «всплесков» в звуке, так что зависимость тут вполне прямая.
Как подсказали в комментариях, можно использовать преобразование Фурье для непосредственной конвертации картинки в звук. Сделанный по-быстрому тест показывает такие результаты (картинки те же):
Тест-1: cloud.mail.ru/public/2C5Z/5MEQ8Swjo
Тест-2: cloud.mail.ru/public/2dxp/3sz8mjAib
Тест-3: cloud.mail.ru/public/3NjJ/ZYrfdTYrk
Тесты звучат интересно, по крайней мере, для маленького и большого квадратов (файлы 1 и 3) разница на слух хорошо ощутима. А вот форма фигур (1 и 2) практически не различается, так что тут тоже есть над чем подумать. Но в целом, звучание полученное с помощью FFT, на слух мне нравится больше.
Заключение
Данный тест, разумеется, не диссертация, а просто proof of concept, сделанный за несколько часов свободного времени. Но даже так, оно в принципе работает, и разницу ощущать на слух вполне реально. Я не знаю, можно ли научиться ориентироваться в пространстве по таким звукам, гипотетически наверно можно после некоторой тренировки. Хотя тут огромное поле для улучшений и экспериментов, например, можно использовать стереозвук, что позволит лучше разделять объекты с разных сторон, можно экспериментировать с другими способами конвертации изображения в звук, например, кодировать цвет разными частотами, и пр. И наконец, перспективным тут является использование 3d-камер, способных воспринимать глубину (увы, такой камеры в наличии нет). Кстати, с помощью несложного кода на OpenCV, вышеприведенный алгоритм можно адаптировать к использованию web-камеры, что позволит экспериментировать с динамическими изображениями.
Ну и как обычно, всем удачных экспериментов.