我正在为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没有无符号的右移或左移,这意味着>>和<<是带符号的右移,其意义比我想象的还要重要。就设计答案而言,这是其他语言所没有的挑战。下面接受的答案对此进行了解释,并且还显示了按位旋转的正确方法。
答案 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位数字上进行。