Ваш код выглядит в основном правильно (при условии, что цель состоит в том, чтобы повторно использовать более короткие входные данные, возвращаясь к началу), но у ваших выходных данных есть небольшая проблема: это не фиксированная ширина на символ, так что вы можете получить один и тот же результат из двух объединяет символы с небольшой (< 16) разницей, как от одной пары символов с большой разницей.
Предполагая, что вы работаете только со "байтовоподобными" строками (все входные данные имеют порядковые значения ниже 256), вы захотите дополнить свой шестнадцатеричный вывод фиксированной шириной, равной двум, с изменяющимися нулями:
xored.append(hex(xored_value)[2:])
to:
xored.append('{:02x}'.format(xored_value))
, который сохраняет временную строку (hex
+ срез делает более длинную строку, а затем срезает префикс, когда строки форматирования могут напрямую генерировать результат без префикса) и ноль на ширину два.
Возможны и другие улучшения для большего количества Pythonic / исполняющего кода, но этого должно быть достаточно, чтобы ваш код давал полезные результаты.
Примечание: при запуске вашего исходного кода xor_two_str('abc', 'ab')
и xor_two_str('ab', 'abc')
оба выдали один и тот же результат, 002
( Попробуйте онлайн! ), чего вы и ожидали ( поскольку xor-ing является коммутативным, и вы циклически сокращаете ввод, обращение аргументов к любому вызову должно привести к тем же результатам). Не уверен, почему вы думаете, что это произвело 5a
. Мой фиксированный код ( Попробуйте онлайн! ) просто выводит 000000
, 000002
, 000002
и 00
; дополнены правильно, но в остальном неизменны от ваших результатов.
Что касается других улучшений, то ручное преобразование символа за символом и ручное циклическое переключение более короткого ввода с помощью остатка и индексации является удивительно дорогостоящей частью этого кода по сравнению с фактически выполненной работой. Вы можете сделать несколько вещей, чтобы уменьшить эти издержки, в том числе:
str
в bytes
один раз, заранее, навалом (выполняется примерно за один седьмое время самого быстрого преобразования символов в символы) itertools.cycle
, чтобы расширить ее по мере необходимости, и zip
, чтобы напрямую выполнить итерацию парные значения байтов, а не индексирование вообще Вместе это дает вам:
from itertools import cycle
def xor_two_str(a,b):
# Convert to bytes so we iterate by ordinal, determine which is longer
short, long = sorted((a.encode('latin-1'), b.encode('latin-1')), key=len)
xored = []
for x, y in zip(long, cycle(short)):
xored_value = x ^ y
xored.append('{:02x}'.format(xored_value))
return ''.join(xored)
или, чтобы сделать его еще более кратким / быстрым, мы просто делаем объект bytes
без преобразования в hex (и просто для удовольствия, используйте map
+ operator.xor
, чтобы полностью исключить необходимость создания петель уровня Python, перенося всю работу на слой C в CPython эталонный интерпретатор), затем преобразуйте в hex str
оптом с помощью (новый в 3.5) bytes.hex
метод :
from itertools import cycle
from operator import xor
def xor_two_str(a,b):
short, long = sorted((a.encode('latin-1'), b.encode('latin-1')), key=len)
xored = bytes(map(xor, long, cycle(short)))
return xored.hex()
Я не могу найти ссылки, но я могу дать основную идею о том, как работают эффекты искажения.
ключ к искажению является функцией, которая берет две координаты (x, y) в искаженном изображении, и преобразовывает их к координатам (u, v) в исходном изображении. Это определяет обратную функцию искажения, так как это забирает искаженное изображение к исходному изображению
Для генерации искаженного изображения, циклов по X и Y, вычисляет точку (u, v) от (x, y) использование обратной функции искажения, и устанавливает компоненты цвета в (x, y) для совпадения с теми в (u, v) в исходном изображении. Каждый ususally использует интерполяцию (например, http://en.wikipedia.org/wiki/Bilinear_interpolation ) для определения цвета в (u, v), так как (u, v) обычно не лежит точно на центре пикселя, а скорее в некоторой дробной точке между пикселями.
скручивание А является по существу вращением, где угол вращения зависит от расстояния от центра изображения. Пример был бы:
a = amount of rotation
b = size of effect
angle = a*exp(-(x*x+y*y)/(b*b))
u = cos(angle)*x + sin(angle)*y
v = -sin(angle)*x + cos(angle)*y
Здесь, я предполагаю для простоты, что центр скручивания в (0,0). Скручивание может быть помещено где угодно путем вычитания координат положения скручивания из X и Y перед функцией искажения и добавления их к Вам и v после него.
вокруг существуют различные эффекты скручивания: некоторые (как вышеупомянутое) скручиваются только локализованная область и имеют сумму скручивания, уменьшающегося к краю изображения. Другие увеличивают скручивание к краю изображения. Этот вид вещи может быть сделан, играя с углом = строка, например,
angle = a*(x*x+y*y)
Существует реализация Java партии фильтров/эффектов изображения в Фильтры Изображения Java Jerry's . Возможно, можно взять вдохновение оттуда.
Скручивание и другие как оно являются матричным преобразованием на пиксельных местоположениях. Вы делаете новое изображение и получаете цвет от позиции по изображению, которое Вы получаете от умножения текущей позиции матрицей.
матрица зависит от текущей позиции.
вот хороший CodeProject, показывающий, как сделать это
http://www.codeproject.com/KB/GDI-plus/displacementfilters.aspx
Смотрите на ImageMagick. Это - преобразование изображения и редактирующий инструментарий и имеет интерфейсы для всех популярных языков.
- перемещают оператор, может создать скручивания с корректной картой смещения.
, Если Вы по некоторым причинам не удовлетворены интерфейсом ImageMagick, можно всегда смотреть на исходный код фильтров и идти оттуда.
есть новая графическая библиотека с множеством функций