Add SetBit, and FlipBit methods to block
This commit is contained in:
parent
e552e1a6f8
commit
9a9cd05bed
@ -126,6 +126,12 @@ namespace Leonetienne::GCrypt {
|
|||||||
//! Will return the state of any given bit
|
//! Will return the state of any given bit
|
||||||
[[nodiscard]] bool GetBit(const std::size_t index) const;
|
[[nodiscard]] bool GetBit(const std::size_t index) const;
|
||||||
|
|
||||||
|
//! Will set the state of any given bit
|
||||||
|
void SetBit(const std::size_t index, const bool state);
|
||||||
|
|
||||||
|
//! Will flip the state of any given bit
|
||||||
|
void FlipBit(const std::size_t index);
|
||||||
|
|
||||||
//! Returns 32-bit chunks of data, indexed by matrix coordinates (0-3)
|
//! Returns 32-bit chunks of data, indexed by matrix coordinates (0-3)
|
||||||
[[nodiscard]] std::uint32_t& Get(const std::uint8_t row, const std::uint8_t column);
|
[[nodiscard]] std::uint32_t& Get(const std::uint8_t row, const std::uint8_t column);
|
||||||
//! Returns 32-bit chunks of data, indexed by matrix coordinates (0-3)
|
//! Returns 32-bit chunks of data, indexed by matrix coordinates (0-3)
|
||||||
|
@ -455,7 +455,47 @@ namespace Leonetienne::GCrypt {
|
|||||||
// Fetch bit index relative to that int
|
// Fetch bit index relative to that int
|
||||||
const std::size_t relBitIndex = index - (intIndex * CHUNK_SIZE_BITS);
|
const std::size_t relBitIndex = index - (intIndex * CHUNK_SIZE_BITS);
|
||||||
|
|
||||||
return data[intIndex] & (1 << (CHUNK_SIZE_BITS - relBitIndex - 1));
|
// Pre-calculate the bitmask to use
|
||||||
|
const std::size_t bitmask = 1 << (CHUNK_SIZE_BITS - relBitIndex - 1);
|
||||||
|
|
||||||
|
return data[intIndex] & bitmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Block::SetBit(const std::size_t index, const bool state) {
|
||||||
|
// Fetch index of integer the bit is located in
|
||||||
|
const std::size_t intIndex = index / CHUNK_SIZE_BITS;
|
||||||
|
|
||||||
|
// Fetch bit index relative to that int
|
||||||
|
const std::size_t relBitIndex = index - (intIndex * CHUNK_SIZE_BITS);
|
||||||
|
|
||||||
|
// Pre-calculate the bitmask to use
|
||||||
|
const std::size_t bitmask = 1 << (CHUNK_SIZE_BITS - relBitIndex - 1);
|
||||||
|
|
||||||
|
// Set the bit
|
||||||
|
if (state) {
|
||||||
|
data[intIndex] |= bitmask;
|
||||||
|
}
|
||||||
|
// Clear the bit
|
||||||
|
else {
|
||||||
|
data[intIndex] &= ~bitmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Block::FlipBit(const std::size_t index) {
|
||||||
|
// Fetch index of integer the bit is located in
|
||||||
|
const std::size_t intIndex = index / CHUNK_SIZE_BITS;
|
||||||
|
|
||||||
|
// Fetch bit index relative to that int
|
||||||
|
const std::size_t relBitIndex = index - (intIndex * CHUNK_SIZE_BITS);
|
||||||
|
|
||||||
|
// Pre-calculate the bitmask to use
|
||||||
|
const std::size_t bitmask = 1 << (CHUNK_SIZE_BITS - relBitIndex - 1);
|
||||||
|
|
||||||
|
data[intIndex] ^= bitmask;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t& Block::Get(const std::uint8_t row, const std::uint8_t column){
|
std::uint32_t& Block::Get(const std::uint8_t row, const std::uint8_t column){
|
||||||
|
@ -648,3 +648,60 @@ TEST_CASE(__FILE__"/get-bit", "[Block]") {
|
|||||||
REQUIRE(ss.str() == a.ToString());
|
REQUIRE(ss.str() == a.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests that the set-bit to-false method works
|
||||||
|
TEST_CASE(__FILE__"/set-bit-to-false", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
a.SetBit(5, 0);
|
||||||
|
a.SetBit(15, 0);
|
||||||
|
a.SetBit(105, 0);
|
||||||
|
a.SetBit(205, 0);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a.GetBit(5) == false);
|
||||||
|
REQUIRE(a.GetBit(15) == false);
|
||||||
|
REQUIRE(a.GetBit(105) == false);
|
||||||
|
REQUIRE(a.GetBit(205) == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that the set-bit to-true method works
|
||||||
|
TEST_CASE(__FILE__"/set-bit-to-true", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
a.SetBit(5, 1);
|
||||||
|
a.SetBit(15, 1);
|
||||||
|
a.SetBit(105, 1);
|
||||||
|
a.SetBit(205, 1);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a.GetBit(5) == true);
|
||||||
|
REQUIRE(a.GetBit(15) == true);
|
||||||
|
REQUIRE(a.GetBit(105) == true);
|
||||||
|
REQUIRE(a.GetBit(205) == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests that the flip-bit method works
|
||||||
|
TEST_CASE(__FILE__"/flip-bit", "[Block]") {
|
||||||
|
// Setup
|
||||||
|
Block a = Key::FromPassword("Halleluja");
|
||||||
|
|
||||||
|
std::string compare = a.ToString();
|
||||||
|
compare[5] = compare[5] == '1' ? '0' : '1';
|
||||||
|
compare[15] = compare[15] == '1' ? '0' : '1';
|
||||||
|
compare[105] = compare[105] == '1' ? '0' : '1';
|
||||||
|
compare[205] = compare[205] == '1' ? '0' : '1';
|
||||||
|
|
||||||
|
// Exercise
|
||||||
|
a.FlipBit(5);
|
||||||
|
a.FlipBit(15);
|
||||||
|
a.FlipBit(105);
|
||||||
|
a.FlipBit(205);
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
REQUIRE(a.ToString() == compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user