Я хочу использовать функцию Perl pack() для кодирования некоторых данных. Затем я хочу сравнить свою упакованную структуру с другой упакованной структурой. Я хочу, чтобы это сравнение было по байтовым значениям этой упакованной структуры.
Согласно документации, cmp использует текущую локаль для определения способа сравнения строк. Но я не хочу, чтобы к сравнению применялся какой-либо интеллект. Я хочу все, что ближе всего к memcmp(). Очевидно, я не могу использовать <=> для сравнения упакованных объектов, поскольку они не являются числами.
Как лучше всего сравнивать упакованные строки в Perl?
Примечание: я читал эту статью об эффективной сортировке в Perl, в которой отмечается, что простая Функция sort использует алгоритм, подобный memcmp, для сравнения структур. Мне интересно, как добиться такого сравнения без использования сортировки.
Ответ 1 · рейтинг 5 · Greg Bacon
Отключите учет локали для блока и используйте cmp как обычно:
sub mycmp {
no locale;
$_[0] cmp $_[1];
}
Документация perlop содержит
lt, le, ge, gt и cmp используют порядок сопоставления (сортировки), указанный в текущей локали, если действует use locale. См. perllocale.
а затем в perllocale
Поведение по умолчанию восстанавливается с помощью прагмы no locale или по достижении конца блока, содержащего use locale.
Например, бег
my($one,$two) = map pack("N", $_) => 1, 2;
say mycmp($one, $two);
say mycmp($two, $one);
выходы
-1
1
Ответ 2 · рейтинг 4 · daxim
Расширить, затем сжать. Сравните, например, шестнадцатеричное представление ваших структур, в котором используются только символы ASCII и не может столкнуться с проблемой локали, которую вы упомянули.
unpack('H*', $first) cmp unpack('H*', $second)
Ответ 3 · deepakg
Здесь мысли вслух - помогут ли побитовые операторы? Подобно тому, как выполнение xor для двух идентичных строк даст битовую строку, в которой все установлено на 0.
http://perldoc.perl.org/perlop.html#Bitwise-String-Operators