如何在dart中创建按位旋转函数?

时间:2019-08-19 23:42:19

标签: dart cryptography bitwise-operators

我正在为Dart(https://pub.dev/packages/steel_crypt)创建加密程序包。现在,我所做的大部分工作都是从PointyCastle或简单的算法中进行的,在这些算法中,不需要按位旋转或可以用>>和<<替换。

但是,当我朝着可以用数学方法完成的复杂密码学解决方案迈进时,我不确定如何在Dart中以最高效率实现按位旋转。由于密码学的性质,速度部分是强调和毫不妥协的,因为我需要绝对最快的实现。

我已经移植了Java的按位旋转方法。我很确定这是正确的,但是不确定效率和可读性:

我经过测试的实现如下:


int INT_BITS = 64; //Dart ints are 64 bit

static int leftRotate(int n, int d) { 

    //In n<<d, last d bits are 0.  
    //To put first 3 bits of n at 
    //last, do bitwise-or of n<<d with 
    //n >> (INT_BITS - d)

    return (n << d) | (n >> (INT_BITS - d)); 
} 

static int rightRotate(int n, int d) { 

    //In n>>d, first d bits are 0.  
    //To put last 3 bits of n at 
    //first, we do bitwise-or of n>>d with 
    //n << (INT_BITS - d)

    return (n >> d) | (n << (INT_BITS - d)); 
}

编辑(为清楚起见):Dart没有无符号的右移或左移,这意味着>>和<<是带符号的右移,其意义比我想象的还要重要。就设计答案而言,这是其他语言所没有的挑战。下面接受的答案对此进行了解释,并且还显示了按位旋转的正确方法。

1 个答案:

答案 0 :(得分:1)

如前所述,Dart没有>>>(无符号右移)运算符,因此您必须依靠带符号的移位运算符。

在这种情况下

int rotateLeft(int n, int count) {
  const bitCount = 64; // make it 32 for JavaScript compilation.
  assert(count >= 0 && count < bitCount);
  if (count == 0) return n;
  return (n << count) | 
      ((n >= 0) ? n >> (bitCount - count) : ~(~n >> (bitCount - count)));
}

应该工作。

此代码仅适用于本机VM。编译为JavaScript时,数字是双精度的,并且按位运算只能在32位数字上进行。