Add SetBit, and FlipBit methods to block

This commit is contained in:
Leonetienne 2022-05-24 23:51:17 +02:00
parent e552e1a6f8
commit 9a9cd05bed
No known key found for this signature in database
GPG Key ID: C33879CD92E9708C
3 changed files with 104 additions and 1 deletions

View File

@ -126,6 +126,12 @@ namespace Leonetienne::GCrypt {
//! Will return the state of any given bit
[[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)
[[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)

View File

@ -455,7 +455,47 @@ namespace Leonetienne::GCrypt {
// Fetch bit index relative to that int
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){

View File

@ -648,3 +648,60 @@ TEST_CASE(__FILE__"/get-bit", "[Block]") {
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);
}