Преобразование Python ctypes.c_int в Perl XS (или не-XS) (преобразование 32-разрядного побитового оператора сдвига в Javascript) - PullRequest
0 голосов
/ 17 сентября 2018

Фон

Нам нужно преобразовать алгоритм хэширования Javascript в код Perl. Следовательно, нам нужно преобразовать операторы побитового сдвига Javascript <<, >> и >>> в Perl. До сих пор у нас есть алгоритмы для преобразования, но поскольку операторы побитового сдвига Javascript работают с 32-разрядными целыми числами, нам также нужно эмулировать это в Perl.

Python-решение

На основании этого поста https://stackoverflow.com/a/41610348 мы узнали, что мы можем сделать это в Python, используя ctypes. Например, чтобы сдвинуть влево целое число на x битов:

import ctypes
print (ctypes.c_int(integer << x ^ 0).value)

Perl вопрос

Насколько я понимаю, нам нужно использовать XS для этого. У меня вопрос, есть ли у кого-нибудь быстрое решение для его реализации. Мы не знаем XS. Мы могли бы начать изучать его, но, судя по моему впечатлению, кривая обучения довольно высока, и может потребоваться некоторое время, чтобы овладеть им. Конечно, не-XS решение было бы идеальным, если оно существует. Любые решения или советы будут с благодарностью.

Обход

Поскольку у нас уже есть решение на Python, мы могли бы реализовать этот модуль на Python, а затем вызвать его из Perl. Производительность на самом деле не проблема, поэтому этот «взлом» приемлем, хотя и несколько нежелателен. Другими словами, мы бы предпочли поддерживать всю программу (которая состоит из нескольких модулей) только на Perl.

1 Ответ

0 голосов
/ 17 сентября 2018
sub lshr32 { ( $_[0] & 0xFFFFFFFF ) >> $_[1] }                           # >>> in JS
sub lshl32 { ( $_[0] << $_[1] ) & 0xFFFFFFFF }

sub ashr32 { ( $_[0] - ( $_[0] % ( 1 << $_[1] ) ) ) / ( 1 << $_[1] ) }   # >> in JS
sub ashl32 { unpack "l", pack "l", $_[0] * ( 1 << $_[1] ) }              # << in JS

Нет смысла передавать отрицательное число логическому сдвигу, если только число не является числом, а набором битов.Учитывая, что вы переносите алгоритм хеширования, это очень вероятно.Это также означает, что вы создаете много дополнительной работы для себя, сопоставляя JavaScript так близко, потому что вы воссоздаете хаки, используемые для устранения ограничений в JavaScript, которых нет в Perl.Должно быть гораздо проще использовать 32-битные значения без знака, <<, усеченные с помощью & 0xFFFFFFFF, и >>, усеченные с помощью & 0xFFFFFFFF.

...