Python ctypes.c_int Perl XS(或非 XS)转换(Javascript 签名的 32 位按位移位



Background

我们需要将 Javascript 哈希算法转换为 Perl 代码。因此,我们需要将 Javascript 的按位移位运算符 <<、>> 和>>> 转换为 Perl。到目前为止,我们已经有了进行转换的算法,但是由于Javascript按位移位运算符对32位整数进行操作,因此我们还需要在Perl中模拟它。

蟒蛇解决方案

基于这篇文章 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 中维护整个程序(由几个模块组成(。

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 中不存在的限制的黑客。使用 32 位无符号值应该简单得多,<<使用& 0xFFFFFFFF截断,>>使用& 0xFFFFFFFF截断。

最新更新