Создайте программу, которая может переставлять пиксели в изображении, чтобы его нельзя было распознать. Однако ваша программа должна иметь возможность преобразовать его обратно в исходное изображение.
Вы можете написать две функции - для кодирования и декодирования, однако одна функция, которая применяется неоднократно, дает оригинальное изображение (пример в математике - f(x) = 1 - x
) является бонусом.
Кроме того, создание некоторого шаблона в выводе также дает бонус.
Изображение может быть представлено в виде 1D / 2D-массива или объекта изображения, если ваш язык поддерживает это. Обратите внимание, что вы можете изменить только порядок пикселей!
Будет логично выбрать в качестве кода победителя, который производит менее узнаваемое изображение, однако я не знаю, как его точно измерить, все способы, которые я могу себе представить, могут быть обмануты. Поэтому я выбрал этот вопрос как конкурс на популярность - пусть пользователи выбирают лучший ответ!
Тестовое изображение 1 (800 x 422 px): Тестовое изображение 2 (800 x 480 px): Пожалуйста, предоставьте выходное изображение кода.
Ответы:
Python 2.7 (с PIL) - нет псевдослучайности
Я разбиваю изображение на 2 на 2 блока (игнорируя остаток) и поворачиваю каждый блок на 180 градусов, затем делаю то же самое с 3 на 3 блоками, затем 4 и т. Д. До некоторого параметра BLKSZ. Затем я делаю то же самое для BLKSZ-1, затем BLKSZ-2, вплоть до 3, а затем 2. Этот метод полностью меняет себя; функция расшифровки - это функция шифрования.
Код :
В зависимости от размера блока, вы можете сделать так, чтобы вычисления уничтожали все сходство с исходным изображением: (BLKSZ = 50)
Или сделайте вычисления эффективными: (BLKSZ = 10)
источник
BLKSZ = 10
Пейзаж это действительно круто!C #, Winform
Редактировать Изменяя способ заполнения массива координат, вы можете иметь разные шаблоны - см. Ниже.
Вам нравится этот тип картины?
Бонус:
Произвольная замена ровно один раз всех пикселей в верхней половине со всеми пикселями в нижней половине. Повторите ту же процедуру для расшифровки (бонус).
Код
Scramble.cs
Scramble.designer.cs
Program.cs
Установите флажок «Небезопасный код» в свойстве проекта для компиляции.
Сложная картина
Измените первую часть рабочей функции, вплоть до Application.DoEvents:
источник
С, произвольное размытие, легко обратимый
Поздно на вечеринку. Вот моя запись!
Этот метод делает скремблирующее размытие. Я называю это схваткой . Это очень просто. В цикле он выбирает случайный пиксель и затем меняет его на случайно выбранный соседний пиксель в модели тороидального холста. Вы указываете максимальное расстояние, определяющее, что означает «соседний пиксель» (1 означает, что всегда выбирается соседний пиксель), количество итераций и, необязательно, начальное число случайных чисел. Чем больше максимальное расстояние и чем больше число итераций, тем более размытым будет результат.
Это обратимо, если указать отрицательное число итераций (это просто удобство интерфейса командной строки; фактически нет такой вещи, как отрицательные итерации). Внутренне он использует собственный 64-разрядный LCPRNG (генератор линейных конгруэнтных псевдослучайных чисел) и предварительно генерирует блок значений. Таблица позволяет циклически проходить через блок вперед или назад для скремблирования или дешифрования соответственно.
демонстрация
Для первых двух изображений при прокрутке вниз каждое изображение размыто с использованием более высокого максимального смещения: самым верхним является исходное изображение (например, смещение на 0 пикселей), за которым следуют 1, 2, 4, 8, 16, 32, 64 , 128 и, наконец, 256. Число итераций составляет 10⁶ = 1 000 000 для всех изображений ниже.
Для вторых двух изображений каждое изображение размыто с использованием постепенно уменьшающегося смещения - например, от наиболее размытого до наименее размытого - от максимального смещения от 256 до 0. Наслаждайтесь!
А для следующих двух изображений вы можете увидеть прогрессии в полном размере здесь и здесь :
Код
Я взломал это вместе примерно через час, когда проснулся этим утром, и в нем почти нет документации. Я мог бы вернуться через несколько дней и добавить дополнительную документацию позже, если люди об этом попросят.
источник
Python 3.4
При достижении бонуса 2 при использовании дополнительного ключевого изображения бонус 1 не теряется. Программа по-прежнему самообращена при условии, что она снова запускается с тем же ключевым изображением.
Стандартное использование
Тестовое изображение 1:
Тестовое изображение 2:
Запуск программы с одним файлом изображения в качестве аргумента сохраняет файл изображения с равномерно скремблированными пикселями по всему изображению. Повторный запуск с зашифрованным выводом сохраняет файл изображения с примененным скремблированием, который восстанавливает оригинал, поскольку процесс скремблирования имеет свой собственный обратный процесс.
Процесс скремблирования является самообращенным, потому что список всех пикселей разбит на 2 цикла, так что каждый пиксель заменяется одним и только одним другим пикселем. Второй запуск приводит к замене каждого пикселя на тот, с которым он был вначале заменен, и все возвращается к тому, как это началось. Если есть нечетное количество пикселей, будет один, который не перемещается.
Благодаря ответу mfvonh как первому предложить 2 цикла.
Использование с ключевым изображением
Скремблирующее тестовое изображение 1 с тестовым изображением 2 в качестве ключевого изображения
Скремблирующее тестовое изображение 2 с тестовым изображением 1 в качестве ключевого изображения
Запуск программы со вторым аргументом файла изображения (изображение ключа) делит исходное изображение на области на основе изображения ключа. Каждая из этих областей разделена на 2 цикла по отдельности, так что все скремблирование происходит внутри областей, и пиксели не перемещаются из одной области в другую. Это распределяет пиксели по каждой области, и таким образом области становятся однородным крапчатым цветом, но с немного другим средним цветом для каждой области. Это дает очень грубое приближение к ключевому изображению в неправильных цветах.
При повторном запуске меняются одинаковые пары пикселей в каждой области, поэтому каждая область восстанавливается в исходное состояние, и изображение в целом снова появляется.
Благодаря EDC65 ответ как первый предложил разделить изображение на регионы. Я хотел бы расширить это, чтобы использовать произвольные регионы, но подход замены всего в области 1 на все в области 2 означал, что регионы должны быть одинакового размера. Мое решение состоит в том, чтобы сохранить регионы изолированными друг от друга и просто перетасовать каждый регион в себя. Поскольку области больше не должны быть одинакового размера, становится проще применять области произвольной формы.
Код
Запись изображения JPEG
Файлы .jpg обрабатываются очень быстро, но за счет слишком горячей работы. Это оставляет сгоревшее изображение после восстановления оригинала:
А если серьезно, формат с потерями приведет к тому, что некоторые цвета пикселей будут слегка изменены, что само по себе делает вывод недействительным. Когда используется ключевое изображение и перетасовка пикселей ограничена областями, все искажения сохраняются в той области, в которой они произошли, а затем равномерно распределяются по этой области при восстановлении изображения. Разница в среднем искажении между областями оставляет видимую разницу между ними, поэтому области, используемые в процессе скремблирования, все еще видны на восстановленном изображении.
Преобразование в формат .png (или любой другой формат без потерь) перед скремблированием гарантирует, что нешифрованное изображение идентично оригиналу без прожигания или искажения:
Маленькие детали
источник
Вот неслучайное преобразование для изменения
nx
разny
разПреобразование является почти самообращенным, повторение преобразования в общей сложности несколько
size_x
раз (в направлении x) возвращает исходное изображение. Я не разобрался с точной математикой, но использование целых кратныхint(log_2(size_x))
дает лучшую перетасовку с наименьшими призрачными изображениямиВот так выглядят первые шаги 20 итераций (nx = ny, обратите внимание на эффект разных разрешений)
источник
Mathematica
Это довольно просто. Я выбираю
5 * nPixels
случайные пары координат и меняю местами эти два пикселя (что полностью скрывает картинку). Чтобы расшифровать его, я делаю то же самое в обратном порядке. Конечно, мне нужно запустить PRNG, чтобы получить одинаковые пары координат на обоих шагах.Единственная разница между двумя функциями заключается
Reverse@
вunscramble
. Обе функции принимают фактический объект изображения. Вы можете использовать их следующим образом:out
иin
идентичны. Вот как этоscr
выглядит:источник
FindPermutation
хотя?{c, a, b}[[{2, 3, 1}]]
можно использовать?C # (+ бонус за симметричный алгоритм)
Это работает, находя
x
такое, чтоx^2 == 1 mod (number of pixels in image)
, а затем умножая индекс каждого пикселя наx
, чтобы найти его новое местоположение. Это позволяет использовать точно такой же алгоритм для шифрования и расшифровки изображения.источник
1
(исходное изображение) иmodulo-1
(перевернутое / перевернутое изображение). Большинство чисел имеют нетривиальные решения, но , похоже , есть некоторые исключения . (связано с первичной факторизациейmodulo
)1
выводит исходное изображение и-1
выводит, например, imgur.com/EiE6VW2C #, самообратный, нет случайности
Если исходное изображение имеет размеры, равные степени двух, то каждая строка и столбец заменяются строкой и столбцом, имеющим инвертированный битовый шаблон, например, для изображения шириной 256, тогда строка 0xB4 заменяется строкой 0x2D. Изображения других размеров делятся на прямоугольники со сторонами степеней 2.
Первое изображение:
Второе изображение:
источник
C #
Тот же метод для шифрования и расшифровки. Буду признателен за предложения по улучшению этого.
Вывод результатов в психоделический плед
источник
Python 2 (обратный, без случайности, контекстно-зависимый)
Это не принесет никаких призов за «наименее узнаваемый», но, возможно, он может быть оценен как «интересный». :-)
Я хотел сделать что-то контекстно-зависимое, где скремблирование пикселей на самом деле зависит от самого изображения.
Идея довольно проста: отсортировать все пиксели по некоторому произвольному значению, полученному из цвета пикселя, а затем поменять местами позиции первого пикселя в этом списке с последним, второго с второго до последнего и т. Д.
К сожалению, в этом простом подходе есть проблема с пикселями одного цвета, поэтому, чтобы сделать его самообращенным, моя программа стала немного сложнее ...
Это результат:
Вы можете достичь совершенно разных результатов, изменив хеш-функцию
f
:r-g-b
:r+g/2.**8+b/2.**16
:math.sin(r+g*2**8+b*2**16)
:(r+g+b)//600
:0
:источник
Mathematica (+ бонус)
Это сворачивает цветовые каналы и скремблирует изображение как один длинный список данных. В результате получается еще менее узнаваемая зашифрованная версия, поскольку она не имеет такого же цветового распределения, как оригинал (поскольку эти данные тоже были зашифрованы). Это наиболее очевидно на втором скремблированном изображении, но если вы присмотритесь, вы увидите тот же эффект и на первом. Функция является собственной обратной.
Был комментарий, что это может быть недопустимо, потому что он скремблирует на канал. Я думаю, что это должно быть, но это не имеет большого значения. Единственное изменение, необходимое для шифрования целых пикселей (вместо каждого канала), должно быть изменено
Flatten @ x
наFlatten[x, 1]
:)объяснение
Определяет функцию,
f
которая принимает 2-мерный массивx
. Функция использует произведение размеров изображения в качестве случайного начального числа, а затем выравнивает массив до одномерного спискаf
(локально затененного). Затем он создает список в форме,{1, 2, ... n}
гдеn
есть длинаf
, случайным образом переставляет этот список, разбивает его на сегменты по 2 (например,{{1, 2}, {3, 4}, ...}
(отбрасывая последнее число, если оба измерения нечетные), а затем переставляетf
, меняя значения на позиции, указанные в каждом только что созданном подсписке, и, наконец, он преобразует пермутированный список обратно в исходные размерыx
. Он скремблирует на канал, потому что помимо свертывания размеров изображенияFlatten
Команда также сворачивает данные канала в каждом пикселе. Функция является собственной обратной, потому что циклы включают в себя только два пикселя каждый.использование
Вот с помощью
Flatten[x, 1]
.источник
f @ f @ img1 // Image
есть (в полном синтаксисе)Image[f[f[img1]]]
Матлаб (+ бонус)
Я в основном переключаю положение двух пикселей наугад и помечаю каждый пиксель, который был переключен, чтобы он не переключался снова. Тот же сценарий можно использовать снова для «расшифровки», потому что я каждый раз сбрасываю генератор случайных чисел. Это делается до тех пор, пока почти все пиксели не переключатся (поэтому размер шага больше 2)
РЕДАКТИРОВАТЬ: Просто увидел, что Мартин Бюттнер использовал аналогичный подход - я не собирался копировать идею - я начал писать свой код, когда не было ответов, извините за это. Я все еще думаю, что моя версия использует несколько разных идей =) (И мой алгоритм гораздо более неэффективен, если вы посмотрите на бит, где выбираются две случайные координаты ^^)
Картинки
Код
источник
Mathematica - используйте перестановку для шифрования и обратную для расшифровки.
Изображение jpg - это трехмерный массив
{r,g,b}
цветов пикселей. (3 измерения структурируют набор пикселей по строке, столбцу и цвету). Он может быть сведен в список{r,g,b}
троек, затем переставлен согласно «известному» списку циклов и, наконец, повторно собран в массив исходных измерений. Результатом является зашифрованное изображение.Unscramble берет зашифрованное изображение и обрабатывает его в обратной последовательности списка циклов. Это выводит, да, оригинальное изображение.
Таким образом, одна функция (в данном случае
scramble
) служит для скремблирования, а также для скремблирования пикселей в изображении.Изображение вводится вместе с начальным номером (чтобы гарантировать, что генератор случайных чисел будет в одном и том же состоянии для скремблирования и дешифрования). Когда параметр reverse является False, функция будет шифроваться. Когда это правда, функция расшифровывается.
свалка
Пиксели сглаживаются и генерируется случайный список циклов. Перестановка использует циклы для переключения позиций пикселей в плоском списке.
расшифровывать
Эта же функция
scramble
используется для расшифровки. Однако порядок списка циклов меняется на противоположный.Примеры
Это же семя (37) используется для скремблирования и скремблирования.
Это производит зашифрованное изображение горы. На рисунке ниже показано, что переменная scrambledMount может быть заменена реальным изображением горной сцены.
Теперь мы запускаем обратное; scrambledMount введен и исходное изображение восстановлено.
То же самое для кругов:
источник
питон
Мне нравится эта головоломка, он показался мне интересным, и я пришел с функцией обтекания и движения, чтобы применить ее к изображению.
Wraped
Я читаю картинку как текст (слева направо, вверх и вниз) и пишу ее как раковину улитки.
Эта функция является циклической: в N есть f, f (n) (x) = x, например, для изображения 4 * 2, f (f (f (x))) = x
движение
Я беру случайное число и перемещаю каждый столбец и строку из него
Код
Фотографий
Первый поворот:
затем перестановка:
И с последним поворотом:
Что касается другого примера:
источник
VB.NET (+ бонус)
Это использует идею flawr, благодаря ему, однако это использует другой алгоритм обмена и проверки. Программа кодирует и декодирует одинаково.
Выходные изображения:
источник
После напоминания о том, что это собирается поменять пиксели, а не изменять их, вот мое решение для этого:
Яичница:
Восстановлен
Это делается путем рандомизации порядка пикселей, но для возможности его восстановления рандомизация фиксируется. Это делается с помощью псевдослучайного числа с фиксированным начальным числом и генерирования списка индексов, которые описывают, какие пиксели нужно поменять местами. Поскольку своп будет таким же, тот же список восстановит исходное изображение.
Обратите внимание, что использование этого алгоритма в формате сжатия с потерями не приведет к тому же результату, так как формат изображения изменит данные. Это должно хорошо работать с любым кодеком без потерь, таким как PNG.
источник
Mathematica
Мы определяем вспомогательную функцию
h
и функцию скремблированияscramble
как:После загрузки изображения, вы можете назвать ,
scramble[img, k]
гдеk
любое целое число, чтобы засекретить изображение. Звоню снова с-k
волей. (Еслиk
есть0
, то никаких изменений не производится.) Как правило,k
должно быть выбрано что-то вроде100
, что дает довольно скремблированное изображение:источник
Matlab: скремблирование строк и столбцов на основе инвариантов суммы строк / столбцов
Это казалось забавной головоломкой, поэтому я подумал об этом и придумал следующую функцию. Он основан на неизменности сумм значений пикселей в строках и столбцах во время циклического сдвига: он сдвигает каждую строку, затем каждый столбец на общую сумму значений пикселей строки / столбца (предполагая, что uint8 для целого числа в переменной shift) ). Это можно затем изменить путем смещения каждого столбца, а затем строки на их суммарное значение в противоположном направлении.
Он не такой красивый, как другие, но мне нравится, что он не случайный и полностью определяется изображением - без выбора параметров.
Первоначально я разработал его для сдвига каждого цветового канала в отдельности, но затем заметил, что спецификация перемещает только полные пиксели.
источник
Ява
Эта программа случайным образом меняет пиксели (создает отображение пиксель в пиксель), но вместо случайной функции она использует Math.sin () (целое число x). Это полностью обратимо. С тестовыми изображениями это создает некоторые образцы.
Параметры: целое число (количество проходов, отрицательное число для реверса, 0 ничего не делает), входной маг и выходное изображение (могут совпадать). Выходной файл должен быть в формате, который использует сжатие без потерь.
1 проход:
100 проходов (это займет несколько минут):
Код:
источник
Python 2.7 с PIL
Немного опоздал на вечеринку, но я подумал, что было бы интересно превратить изображения в пледы (и обратно, конечно). Сначала мы смещаем столбцы вверх или вниз в 4 раза по количеству столбцов (четные столбцы вниз, нечетные столбцы вверх). Затем мы сдвигаем строки влево или вправо в 4 раза по числу строк (четные столбцы влево, нечетные столбцы вправо).
Результат довольно тартанский.
Чтобы изменить, мы просто делаем это в обратном порядке и сдвигаемся на противоположную величину.
Код
Результаты
Плед с картинки 1:
Форма пледа изображение 2:
источник
offset = x*xsize/ysize
иoffset = y*ysize/xsize
, к сожалению, это действительно не скрывает изображение.Python (+ бонус) - перестановка пикселей
В этом методе каждый пиксель будет размещен в другой позиции с ограничением, что другой пиксель будет размещен в первой позиции. Математически это перестановка с длиной цикла 2. Таким образом, метод является собственным обратным.
Оглядываясь назад, он очень похож на mfvonh, но это представление написано на Python, и мне пришлось самому создавать эту перестановку.
Первое тестовое изображение: Второе тестовое изображение:
источник
Python 2.7 + PIL, вдохновение из скользящих головоломок
Просто была другая идея. По сути, этот метод делит изображение на блоки одинакового размера и затем перетасовывает их порядок. Поскольку новый заказ основан на фиксированном начальном числе, можно полностью отменить процесс, используя тот же начальный уровень. Кроме того, с помощью дополнительного параметра, называемого гранулярностью, можно достичь разных и неузнаваемых результатов.
Результаты:
оригинал
Зернистость 16
Зернистость 13
Зернистость 10
Зернистость 3
Зернистость 2
Зернистость 1
оригинал
Зернистость 16
Зернистость 13
Зернистость 10
Зернистость 3
Зернистость 2
Зернистость 1
Код:
источник
47
94 строки. 47 для кодирования, 47 для декодирования.
codegolf-35005_ref.rb
(преобразовано в JPG)
(оригинал уменьшен)
источник
Matlab с щепоткой теории групп (+ бонус)
В этом подходе мы предполагаем, что у нас есть четное количество всех пикселей. (Если нет, мы просто игнорируем один пиксель). Поэтому нам нужно выбрать половину пикселей, чтобы поменять их с другой половиной. Для этого мы индексируем все пиксели от
0
до2N-1
и рассматриваем эти индексы как циклическую группу.Среди простых чисел мы ищем число
p
, которое не слишком мало и не слишком велико, и это взаимно просто2N
, порядок нашей группы. Это значитg
порождает нашу группу или{k*g mod 2N | k=0,1,...,2N-1} = {0,1,...,2N-1}
.Поэтому мы выбираем первые
N
кратныеg
как один набор, а все остальные индексы как другой набор и просто меняем соответствующий набор пикселей.Если
p
выбран правильный путь, первый набор равномерно распределяется по всему изображению.Два теста:
Немного не по теме, но интересно:
Во время тестирования я заметил, что если вы сохраните его в (сжатый с потерями) jpg (вместо сжатого без потерь png) и примените преобразование туда-сюда, вы довольно быстро увидите артефакты сжатия, это покажет результаты двух последовательных перестановок :
Как видите, сжатие jpg делает результат почти черно-белым!
источник
JavaScript (+ бонус) - повторитель обмена с делением пикселей
источник
Python 2.7 + PIL, колонка / строка скремблер
Этот метод просто скремблирует строки и столбцы изображения. Можно шифровать только одно из измерений или оба. Кроме того, порядок новой зашифрованной строки / столбца основан на пароле. Кроме того, другой возможностью является скремблирование всего массива изображений без учета размеров.
Результаты:
Скремблируем все изображение:
Скремблирование колонн:
Скремблирование строк:
Скремблирование столбцов и строк:
Я также попытался применить несколько прогонов к изображению, но конечные результаты не сильно отличались, только сложность его расшифровки.
Код:
источник
C # Winforms
Изображение1:
Изображение 2:
Исходный код:
источник
Python 3.6 + pypng
Riffle / Master Shuffle
Мой алгоритм применяет риффл-тасование в одном направлении и мастер-тасовку в другом (так как оба являются инверсиями друг друга) по несколько итераций в каждой, но каждая обобщается для разделения на любое количество подгрупп, а не только на две. Эффект состоит в том, что вы можете создать многоэтапный ключ перестановки, поскольку изображение не будет восстановлено без знания точной последовательности риффа и мастер-тасов. Последовательность может быть указана с помощью серии целых чисел с положительными числами, представляющими риффы, и отрицательными числами, представляющими мастеров.
Я перетасовал ландшафт ключом [3, -5, 2, 13, -7]:
Интересно, что некоторые интересные вещи происходят из [3, -5], где остаются некоторые артефакты из исходного изображения:
Вот абстрактный рисунок, перемешанный с ключом [2, 3, 5, 7, -11, 13, -17]:
Если в ключе неверен только один параметр, команда unshuffle не восстановит изображение:
источник