XOR две строки разной длины

Методы Метеор являются асинхронными, вы можете получить результат многими способами.

Использование модулей модуля npm (другой ответ объясняет это очень четко).

Есть некоторые другие путь без использования модуля npm:

Через переменную сеанса:

    Meteor.call('myMethod',args, function(error, result) { 
  if (error) { Session.set('result', error) } // Note that the error is returned synchronously 
  else { 
    Session.set('result', result) // Using : Session.get('result') will return you the result of the meteor call !
  }
});

Или через шаблонную переменную:

    Template.hello.onCreated(function helloOnCreated() {
  // counter starts at 0
  this.message = new ReactiveVar(0);
});

Template.hello.helpers({
  message() {
    return Template.instance().message.get();
  },
});

Template.hello.events({
  'click button'(event, instance) {
    Meteor.call('myMethod', args, function (error, result) {
      if (error) { Template.instance().message.set(error); }
      else {
        Template.instance().message.set(result);
      }
    })
  },
});

Надеюсь, что это поможет!

1
задан isherwood 5 March 2019 в 17:13
поделиться

1 ответ

Ваш код выглядит в основном правильно (при условии, что цель состоит в том, чтобы повторно использовать более короткие входные данные, возвращаясь к началу), но у ваших выходных данных есть небольшая проблема: это не фиксированная ширина на символ, так что вы можете получить один и тот же результат из двух объединяет символы с небольшой (< 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; дополнены правильно, но в остальном неизменны от ваших результатов.

Что касается других улучшений, то ручное преобразование символа за символом и ручное циклическое переключение более короткого ввода с помощью остатка и индексации является удивительно дорогостоящей частью этого кода по сравнению с фактически выполненной работой. Вы можете сделать несколько вещей, чтобы уменьшить эти издержки, в том числе:

  1. Конвертировать из str в bytes один раз, заранее, навалом (выполняется примерно за один седьмое время самого быстрого преобразования символов в символы)
  2. Определите заранее, какая строка является самой короткой, и используйте 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()
0
ответ дан ShadowRanger 5 March 2019 в 17:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: