Python: «снять маску» с длинной строки данных, обработанной XORPython

Программы на Python
Ответить
Anonymous
 Python: «снять маску» с длинной строки данных, обработанной XOR

Сообщение Anonymous »


В рамках спецификации WebSocket все кадры, отправленные клиентом, должны иметь часть полезной нагрузки кадров, замаскированную с использованием 4-байтовой маски. На C++ это было бы очень просто:

for (size_t i = 0; i < length; i++) { данные ^= маска[i % 4]; } К сожалению, строки Python неизменяемы, и я бы предпочел избегать подобных действий из-за постоянного копирования и повторного создания строкового буфера:

frame = '' для я в диапазоне (0, длина-1): кадр += chr(ord(oldFrame) ^ ord(маска[i % 4])) Итак, после некоторых исследований я нашел вот это:

m = itertools.cycle(маска) Frame = ''.join(chr(ord(x) ^ ord(y)) для (x,y) в itertools.izip(oldFrame, m)) В CPython это вдвое сократило время, необходимое для демаскирования. В PyPy для замаскированной строки размером 16 МБ это легко увеличивается до 1,5 ГБ ОЗУ, после чего начинается замена, и мне приходится ее убить. CPython использует «всего» 150 МБ ОЗУ для этой строки размером 16 МБ (и это занимает 20 секунд), но это все равно плохо. Для сравнения, мой тест C++ сделал это за 0,05 секунды без каких-либо затрат памяти.

Конечно, это крайности, которых на самом деле не произойдет, когда программное обеспечение перейдет в производственный режим (все входящие данные ограничены 10 КБ), но мне бы очень хотелось получить хороший результат в этом тесте.

Есть идеи? Единственные требования: быстрая работа как на CPython, так и на PyPy, а также низкое использование памяти. Исходную строку сохранять не обязательно.

Небольшой тестовый код для тех, кто хочет поэкспериментировать:
импортировать ОС, время кадр = os.urandom(16
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»