Python ctypes.c_int到Perl XS(或非XS)的转换(JavaScript签名的32位按位移位运算符转换)

时间:2018-09-17 11:10:26

标签: javascript python perl bitwise-operators

背景

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

Python解决方案

基于本文https://stackoverflow.com/a/41610348,我们了解到可以使用ctypes在Python中完成此操作。例如,要将整数左移x位:

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

Perl问题

我的理解是,我们需要使用XS来做到这一点。我的问题是,是否有人可以快速实施该解决方案。我们不知道XS。我们可以开始学习它,但是从我的印象中,学习曲线相当高,可能需要一段时间才能精通它。当然,如果有的话,非XS解决方案将是理想的。任何解决方案或提示将不胜感激。

解决方法

由于我们已经有了Python解决方案,因此我们可以用Python实现此模块,然后从Perl中调用它。性能并不是真正的问题,因此这种“ hack”是可以接受的,尽管有些不可取。换句话说,我们宁愿只在Perl中维护整个程序(由几个模块组成)。

1 个答案:

答案 0 :(得分:5)

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,应该更简单。