learncrypto/source/bitmanip.d

51 lines
1.3 KiB
D

module bitmanip;
private import std.traits : isUnsigned;
private import std.bitmanip : nativeToLittleEndian, littleEndianToNative;
UIntType rotateLeft(UIntType)(in UIntType val, in size_t len) nothrow @nogc pure @safe
if (isUnsigned!UIntType)
{
auto reducedLen = len % (8 * UIntType.sizeof);
return cast(UIntType)((val << reducedLen) | (val >> (8 * UIntType.sizeof - reducedLen)));
}
unittest
{
ubyte[] test = [0, 1, 128];
assert(test[0].rotateLeft(1) == 0);
assert(test[1].rotateLeft(1) == 2);
assert(test[2].rotateLeft(1) == 1);
assert(test[1].rotateLeft(7) == 128);
}
UIntType rotateRight(UIntType)(in UIntType val, in size_t len) nothrow @nogc pure @safe
if (isUnsigned!UIntType)
{
auto reducedLen = len % (8 * UIntType.sizeof);
return cast(UIntType)((val >> reducedLen) | (val << (8 * UIntType.sizeof - reducedLen)));
}
unittest
{
ubyte[] test = [0, 1, 128];
assert(test[0].rotateRight(1) == 0);
assert(test[1].rotateRight(1) == 128);
assert(test[2].rotateRight(1) == 64);
assert(test[2].rotateRight(7) == 1);
}
alias littleEndianInv = nativeToLittleEndian;
uint littleEndian(in ubyte[] input) @safe pure nothrow @nogc
in
{
assert(input.length == uint.sizeof);
}
body
{
ubyte[uint.sizeof] buf = input;
return littleEndianToNative!uint(buf);
}