这是我能想到的旋转任意位数最快的算法(我旋转8字节的数组,您可以轻松将其转换为16位移):
使用EEPROM创建一个掩码表来进行位移。掩码只是从右侧逐渐增加1的数量:
final static byte[] ROTL_MASK = {
(byte) 0x00, //shift 0: 00000000 //this one is never used, we don't do shift 0.
(byte) 0x01, //shift 1: 00000001
(byte) 0x03, //shift 2: 00000011
(byte) 0x07, //shift 3: 00000111
(byte) 0x0F, //shift 4: 00001111
(byte) 0x1F, //shift 5: 00011111
(byte) 0x3F, //shift 6: 00111111
(byte) 0x7F //shift 7: 01111111
};
如果移位大于8位,则首先使用Util.arrayCopyNonAtomic
进行字节快速交换:
final static byte BITS = 8;
Util.arrayCopyNonAtomic(in, (short) (shift/BITS), out, (short) 0, (short) (8-(shift/BITS)));
Util.arrayCopyNonAtomic(in, (short) 0, out, (short) (8-(shift/BITS)), (short) (shift/BITS));
shift %= BITS;
if (shift > 0) {
byte mask = ROTL_MASK[shift];
byte comp = (byte) (8 - shift);
out[8] = in[0];
out[0] = (byte)((byte)(in[0] << shift) | (byte)((in[1] >> comp) & mask));
out[1] = (byte)((byte)(in[1] << shift) | (byte)((in[2] >> comp) & mask));
out[2] = (byte)((byte)(in[2] << shift) | (byte)((in[3] >> comp) & mask));
out[3] = (byte)((byte)(in[3] << shift) | (byte)((in[4] >> comp) & mask));
out[4] = (byte)((byte)(in[4] << shift) | (byte)((in[5] >> comp) & mask));
out[5] = (byte)((byte)(in[5] << shift) | (byte)((in[6] >> comp) & mask));
out[6] = (byte)((byte)(in[6] << shift) | (byte)((in[7] >> comp) & mask));
out[7] = (byte)((byte)(in[7] << shift) | (byte)((in[8] >> comp) & mask));
}
您可以另外删除mask
变量,直接使用对表格的引用。
与位旋转的天真实现相比,使用这种方法证明速度提高了约450% - 500%。
int
或long
...你只有byte
和short
。 - vojtabyteRot
变量的掩码左侧添加一个位集即可。 - Maarten Bodewes