我正在尝试对JavaCard智能卡中当前表示为8字节的字节数组的64位字执行任意数量的旋转。
最丑陋的方法是在一个64位字上硬编码所有64种可能的ROTL排列,表示为一个8字节数组,但这只会使整个代码库膨胀。
我如何使它更精简,这样我可以只使用byte
和short
类型(由于JavaCard不能识别更复杂的东西,如int
或long
等),而不需要硬编码所有的ROTL64排列,在64位字(字节数组中)上按需执行任意数量的ROTL操作。
发布于 2018-09-29 12:46:37
一个非常简单的实现,它在单独的参数中接收四个短路
public static void rotateRight64(short x3, short x2, short x1, short x0,
short rotAmount, short[] out)
{
assert out.length() == 4;
rotAmount &= (1 << 6) - 1; // limit the range to 0..63
if (rotAmount >= 16)
rotateRight64(x0, x3, x2, x1, rotAmount - 16, out);
else
{
out[0] = (short)((x0 >>> rotAmount) | (x1 << (16-rotAmount)));
out[1] = (short)((x1 >>> rotAmount) | (x2 << (16-rotAmount)));
out[2] = (short)((x2 >>> rotAmount) | (x3 << (16-rotAmount)));
out[3] = (short)((x3 >>> rotAmount) | (x0 << (16-rotAmount)));
}
}
这是一个向右旋转,但是通过向右旋转很容易做一个向左旋转64 - rotAmount
或者,可以像这样做,而不需要粗略的移位步骤
public static void rotateRight(short[] out, short[] in, short rotAmount) // in ror rotAmount
{
assert out.length() == 4 && in.length() == 4 && rotAmount >= 0 && rotAmount < 64;
const short shift = (short)(rotAmount % 16);
const short limbshift = (short)(rotAmount / 16);
short tmp = in[0];
for (short i = 0; i < 4; ++i)
{
short index = (short)((i + limbshift) % 4);
out[i] = (short)((in[index] >>> shift) | (in[index + 1] << (16 - shift)));
}
}
这样可以很容易地将其更改为任意精度的移位/旋转
如果输入数组是byte
,那么您可以将short[4]
更改为byte[8]
,并更改16→8和4→8中的所有常量。事实上,它们可以毫无问题地泛化,我只是在进行硬编码,以使其简单易懂
https://stackoverflow.com/questions/52552322
复制相似问题