Files
CPP_Core/psc_global_include/Bit.cpp
T
2026-06-16 10:56:40 +08:00

756 lines
26 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "Bit.h"
#include <bitset>
#include <iomanip>
#include <regex>
#include <sstream>
#include <stdexcept>
// 2025-01-02 05:01:50 [info] 1a480118 9607f81e f020 3a24 67761dbd 1a9ecbf8 5655c75b 00601307
#include <algorithm>
#include <array>
#include <cstring>
#include <string>
#include <string>
#include <utility>
#include <vector>
#include <map>
#include <iostream>
#include <set>
#include <sstream>
#include <unordered_map>
#include <bitset>
#include <cstdint>
#include <cassert>
#ifdef _USE_GTEST
#include <gtest/gtest.h>
using namespace Psc;
#endif
constexpr std::array<uint8_t, 256> make_hex_to_val() {
std::array<uint8_t, 256> t{255}; // 初始化为255
for (uint8_t i = '0'; i <= '9'; ++i) t[i] = i - '0';
for (uint8_t i = 'A'; i <= 'F'; ++i) t[i] = i - 'A' + 10;
for (uint8_t i = 'a'; i <= 'f'; ++i) t[i] = i - 'a' + 10;
return t;
}
constexpr std::array<uint8_t, 16> make_val_to_hex(bool uppercase) {
std::uint8_t s = uppercase ? 'A' : 'a';
std::array<uint8_t, 16> t{};
for (uint8_t i = 0; i < 10; ++i) {
t[i] = '0' + i; // '0' - '9'
}
for (uint8_t i = 10; i < 16; ++i) {
t[i] = s + (i - 10); // 'a' - 'f' 'A - F'
}
return t;
}
static constexpr std::array<uint8_t, 16> val_to_upper_hex = make_val_to_hex(true);
static constexpr std::array<uint8_t, 16> val_to_lower_hex = make_val_to_hex(false);
static constexpr std::array<uint8_t, 256> hex_to_val = make_hex_to_val();
constexpr const char* hex_lut_lower = "0123456789abcdef";
constexpr const char* hex_lut_upper = "0123456789ABCDEF";
constexpr const char* big_dian_hex_to_bin[16] = {
"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"
};
constexpr const char* small_dian_hex_to_bin[16] = {
"0000", "1000", "0100", "1100", "0010", "1010", "0110", "1110",
"0001", "1001", "0101", "1101", "0011", "1011", "0111", "1111"
};
constexpr std::array<std::array<std::uint8_t, 256>, 256> make_xor_table() {
std::array<std::array<std::uint8_t, 256>, 256> t{};
for (size_t i = 0; i < 256; ++i) {
for (size_t j = 0; j < 256; ++j) {
t[i][j] = 255;
}
}
for (size_t i = 0; i < 16; ++i) {
for (size_t j = 0; j < 16; ++j) {
t[val_to_lower_hex[i]][val_to_lower_hex[j]] = i ^ j;
t[val_to_upper_hex[i]][val_to_upper_hex[j]] = i ^ j;
}
}
return t;
}
static constexpr std::array<std::array<std::uint8_t, 256>, 256> xor_table = make_xor_table();
inline size_t bin4_to_hex(bool big_byte_order, const char* a) {
static size_t small_base[]{1, 2, 4, 8};
static size_t big_base[]{8, 4, 2, 1};
auto cur_dian = big_byte_order ? big_base : small_base;
size_t ret = 0;
for (size_t i = 0; i < 4; ++i) {
auto cur = size_t(a[i] - '0');
ret += cur_dian[i] * cur;
}
return ret;
}
namespace Psc {
const bool is_big_endian = []() {
uint16_t x = 0x0102; // 设置一个已知的 16-bit 值
auto* p = reinterpret_cast<uint8_t*>(&x);
return p[0] == 0x01; // 如果 p[0] 为 0x01,说明是大端字节序
}();
std::vector<std::string> split(const std::string& str, const std::string& delimiter) {
std::vector<std::string> tokens;
size_t start = 0;
size_t end = str.find(delimiter);
if (end == std::string::npos) return {};
while (end != std::string::npos) {
tokens.push_back(str.substr(start, end - start));
start = end + 1;
end = str.find(delimiter, start);
}
tokens.push_back(str.substr(start)); // Add the last token
return tokens;
}
std::string bin2mem(const std::string& bin) {
const size_t len = bin.size();
if (len % 8 != 0) {
throw std::invalid_argument("binary string length must be a multiple of 8");
}
std::string result;
result.reserve(len / 8); // 提前分配
for (size_t i = 0; i < len; i += 8) {
uint8_t byte = 0;
for (size_t j = 0; j < 8; ++j) {
char bit = bin[i + j];
if (bit == '1') {
byte |= (1 << (7 - j));
} else if (bit != '0') {
std::ostringstream oss;
oss << "Invalid bit character '" << bit << "' at position " << (i + j);
throw std::invalid_argument(oss.str());
}
}
result.push_back(static_cast<char>(byte));
}
return result;
}
void bin2mem(void* dest, const char* data, size_t size) {
if (size % 8 != 0) {
throw std::invalid_argument("Binary string length must be a multiple of 8");
}
uint8_t* byte_dest = static_cast<uint8_t*>(dest); // 将 dest 转换为字节指针
for (size_t i = 0; i < size; i += 8) {
uint8_t byte = 0;
for (size_t j = 0; j < 8; ++j) {
char bit = data[i + j];
if (bit == '1') {
byte |= (1 << (7 - j)); // 设置相应的位
} else if (bit != '0') {
std::ostringstream oss;
oss << "Invalid bit character '" << bit << "' at position " << (i + j);
throw std::invalid_argument(oss.str());
}
}
byte_dest[i / 8] = byte; // 将转换后的字节写入目标内存
}
}
void hex2mem_Ex(void* dest, const char* data, size_t size) {
// 判断输入 hex 数据的长度是否为偶数
if (size % 2 != 0) {
throw std::invalid_argument("hex string length must be even");
}
// 填充目标数据
for (size_t i = 0; i < size; i += 2) {
unsigned char hi = data[i];
unsigned char lo = data[i + 1];
auto hi_val = hex_to_val[hi];
auto lo_val = hex_to_val[lo];
if (hi_val == 255 || lo_val == 255) {
std::ostringstream oss;
oss << "hex:[" << data << "] Invalid hex: [" << data[i] << data[i + 1] << "] at pos " << i;
throw std::invalid_argument(oss.str());
}
// 填充目标内存
unsigned char byte = (hi_val << 4) | lo_val;
std::memcpy(static_cast<unsigned char*>(dest) + i / 2, &byte, 1);
}
}
void mem2hex_Ex2(void* dest, void* mem, size_t num, bool uppercase, const char* middle, size_t middle_len) {
assert(middle != nullptr);
const char* lut = uppercase ? hex_lut_upper : hex_lut_lower;
if (middle_len == std::numeric_limits<size_t>::max()) {
middle_len = (middle != nullptr) ? std::strlen(middle) : 0;
}
char* dest_ptr = static_cast<char*>(dest);
for (size_t i = 0; i < num; ++i) {
unsigned char c = static_cast<unsigned char*>(mem)[i];
*dest_ptr++ = lut[c >> 4];
*dest_ptr++ = lut[c & 0xF];
// 添加分隔符
if (middle_len > 0 && i + 1 < num) {
std::copy(middle, middle + middle_len, dest_ptr);
dest_ptr += middle_len;
}
}
}
void hex2bin_Ex(void* dest, const char* data, size_t size, bool big_dian) {
auto& dian = big_dian ? big_dian_hex_to_bin : small_dian_hex_to_bin;
for (size_t i = 0; i < size; i++) {
auto str = dian[hex_to_val[(unsigned char)(data[i])]];
std::memmove(static_cast<uint8_t*>(dest) + i * 4, str, 4);
}
}
void
bin2hex_Ex(void* dest, const char* d, size_t size, bool big_dian, bool uppercase) {
const char* lut = uppercase ? hex_lut_upper : hex_lut_lower;
auto tt = get_bin2hex_size(size);
auto n1 = size;
auto n2 = tt * 4;
char cur[4] = {'0', '0', '0', '0'};
auto r = static_cast<std::uint8_t*>(dest);
if (!big_dian) {
// 小端 补充后导0
for (size_t i = 0; i < n2; i++) {
auto j = i%4;
cur[j] = i >= n1 ? '0' : d[i];
if (j == 3) {
auto val = bin4_to_hex(false, cur);
r[tt - 1 - i/4] = lut[val];
}
}
} else {
// 大端模式:补充前导0
for (size_t i = 0; i < n2; i++) {
// 对应位置
auto j = i%4;
cur[j] = i >= n1 ? '0' : d[n1 - 1 - i];
if (j == 3) {
auto val = bin4_to_hex(false, cur);
r[tt - 1 - i/4] = lut[val];
}
}
}
}
#ifdef _USE_GTEST
TEST(Bit2223, bin2hex_Ex) {
// EXPECT_EQ(bin2hex("01101110"), "6E");
//
{
// 0110 1110
// 6 E
std::string it = "1101110";
auto size = get_bin2hex_size(it.size());
std::string res;
res.resize(size);
bin2hex_Ex(res.data(), it.c_str(), it.size(), true, true);
EXPECT_STREQ(res.c_str(), "6E");
}
{
// 1101 1100
// B 3
std::string it = "1101110";
auto size = get_bin2hex_size(it.size());
std::string res;
res.resize(size);
bin2hex_Ex(res.data(), it.c_str(), it.size(), false, true);
// std::cout << res << std::endl;
EXPECT_STREQ(res.c_str(), "3B");
}
}
#endif
void xor_bin_Ex(void* dest, const char* s1, size_t n1, const char* s2, size_t n2, bool big_dian) {
if (n1 > n2) {
std::swap(n1, n2);
std::swap(s1, s2);
}
// n1 <= n2
char* r = static_cast<char*>(dest);
if (!big_dian) {
// 小端 补充后导0
for (size_t i = 0; i < n1; i++) {
r[i] = s1[i] == s2[i] ? '0' : '1';
}
for (size_t i = n1; i < n2; i++) {
r[i] = '0' == s2[i] ? '0' : '1';
}
} else {
// 大端模式:补充前导0
for (size_t i = 0; i < n1; i++) {
// 对应位置
auto c1 = s1[n1 - 1 - i];
auto c2 = s2[n2 - 1 - i];
r[n2 - 1 - i] = c1 == c2 ? '0' : '1'; // 对应位异或
}
for (size_t i = n1; i < n2; i++) {
auto c1 = '0';
auto c2 = s2[n2 - 1 - i];
r[n2 - 1 - i] = c1 == c2 ? '0' : '1'; // 对应位异或
}
}
}
#ifdef _USE_GTEST
TEST(Bit2223, xor_bin_Ex) {
const char* s1 = "10";
const char* s2 = "111";
std::string res;
res.resize(3);
xor_bin_Ex(res.data(), s1, 2, s2, 3, true);
EXPECT_STREQ(res.c_str(), "101");
xor_bin_Ex(res.data(), s1, 2, s2, 3, false);
EXPECT_STREQ(res.c_str(), "011");
xor_bin_Ex(res.data(), s2, 3, s1, 2, false);
EXPECT_STREQ(res.c_str(), "011");
s2 = "1111";
res.resize(4);
// 0010
// 1111
// 1101
xor_bin_Ex(res.data(), s1, 2, s2, 4, true);
EXPECT_STREQ(res.c_str(), "1101");
}
#endif
void xor_hex_Ex(void* dest, const char* s1, size_t n1, const char* s2, size_t n2, bool big_dian, bool uppercase) {
if (n1 > n2) {
std::swap(n1, n2);
std::swap(s1, s2);
}
auto& val_to_hex = uppercase ? val_to_upper_hex : val_to_lower_hex;
// n1 <= n2
auto r = static_cast<std::uint8_t*>(dest);
if (!big_dian) {
// 小端 补充后导0
for (size_t i = 0; i < n1; i++) {
//r[i] = s1[i] == s2[i] ? '0' : '1';
auto c1 = s1[i];
auto c2 = s2[i];
r[i] = val_to_hex[xor_table[c1][c2]];
}
for (size_t i = n1; i < n2; i++) {
//r[i] = '0' == s2[i] ? '0' : '1';
auto c1 = '0';
auto c2 = s2[i];
r[i] = val_to_hex[xor_table[c1][c2]];
}
} else {
// 大端模式:补充前导0
for (size_t i = 0; i < n1; i++) {
// 对应位置
auto c1 = s1[n1 - 1 - i];
auto c2 = s2[n2 - 1 - i];
//r[n2 - 1 - i] = c1 == c2 ? '0' : '1'; // 对应位异或
auto idx = xor_table[c1][c2];
r[n2 - 1 - i] = val_to_hex[idx]; // 对应位异或
}
for (size_t i = n1; i < n2; i++) {
auto c1 = '0';
auto c2 = s2[n2 - 1 - i];
auto idx = xor_table[c1][c2];
//r[n2 - 1 - i] = c1 == c2 ? '0' : '1'; // 对应位异或
r[n2 - 1 - i] = val_to_hex[idx]; // 对应位异或
}
}
}
#ifdef _USE_GTEST
TEST(Bi222, xor_hex_Ex) {
{
const char* s1 = "10";
const char* s2 = "111";
std::string res;
res.resize(3);
xor_hex_Ex(res.data(), s1, 2, s2, 3, true, true);
EXPECT_STREQ(res.c_str(), "101");
xor_hex_Ex(res.data(), s1, 2, s2, 3, false, true);
EXPECT_STREQ(res.c_str(), "011");
xor_hex_Ex(res.data(), s2, 3, s1, 2, false, true);
EXPECT_STREQ(res.c_str(), "011");
}
{
const char* s1 = "ab";
const char* s2 = "111";
std::string res;
res.resize(3);
// 0ab 0000 0110 0111
// 111 0001 0001 0001
// 1ba 0001 0111 0110
xor_hex_Ex(res.data(), s1, 2, s2, 3, true, true);
EXPECT_STREQ(res.c_str(), "1BA");
}
}
#endif
// 将字节序从大端转换到当前平台字节序,并复制到目标内存中
void big_endian_2_platform(const std::string& big_endian, char* dest) {
// 先复制原始数据
std::string result = big_endian;
// 如果当前平台是小端,反转数据
if (!is_big_endian) {
std::reverse(result.begin(), result.end());
}
// 将转换后的数据拷贝到目标内存中
std::memcpy(dest, result.data(), result.size());
}
std::string big_endian_2_platform(const std::string& big_endian) {
std::string result;
result.resize(big_endian.size());
big_endian_2_platform(big_endian, result.data());
return result;
}
// 将字节序从小端转换到当前平台字节序,并复制到目标内存中
void little_endian_2_platform(const std::string& little_endian, char* dest) {
// 先复制原始数据
std::string result = little_endian;
// 如果当前平台是大端,反转数据
if (is_big_endian) {
std::reverse(result.begin(), result.end());
}
// 将转换后的数据拷贝到目标内存中
std::memcpy(dest, result.data(), result.size());
}
std::string little_endian_2_platform(const std::string& little_endian) {
std::string result;
result.resize(little_endian.size());
big_endian_2_platform(little_endian, result.data());
return result;
}
// 将平台字节序转换为大端字节序
std::string platform_2_big_endian(void* t, int size) {
char* memory = reinterpret_cast<char*>(t);
// for (int i = 0; i < size; ++i) {
// std::cout << (int)memory[i] << std::endl;
// }
std::string result(memory, memory + size);
// 如果当前平台是小端,反转字符串,使其成为大端字节序
//std::cout << "platform_2_big_endian start " << memory2hex(result) << std::endl;
if (!is_big_endian) {
std::reverse(result.begin(), result.end());
}
//std::cout << "platform_2_big_endian end " << memory2hex(result) << std::endl;
return result;
}
// 将平台字节序转换为小端字节序
std::string platform_2_little_endian(void* t, int size) {
char* memory = reinterpret_cast<char*>(t);
std::string result(memory, memory + size);
// 如果当前平台是大端,反转字符串,使其成为小端字节序
if (is_big_endian) {
std::reverse(result.begin(), result.end());
}
return result;
}
#define GET_BIT(byte, pos) (((byte) >> (pos)) & 1)
#define SET_BIT(byte, pos) ((byte) |= (1 << (pos)))
#define CLR_BIT(byte, pos) ((byte) &= ~(1 << (pos)))
#define WRITE_BIT(byte, pos, val) \
((byte) = ((byte) & ~(1 << (pos))) | (((val) & 1) << (pos)))
template <typename BitOp>
void bit_op(void* dest, size_t d_offset, const void* src, size_t s_offset, size_t num, BitOp op) {
auto* d = (uint8_t*)dest;
const auto* s = (const uint8_t*)src;
for (size_t i = 0; i < num; ++i) {
size_t src_pos = s_offset + i;
size_t dst_pos = d_offset + i;
uint8_t src_bit = GET_BIT(s[src_pos / 8], src_pos % 8);
uint8_t dst_bit = GET_BIT(d[dst_pos / 8], dst_pos % 8);
uint8_t res_bit = op(dst_bit, src_bit);
WRITE_BIT(d[dst_pos / 8], dst_pos % 8, res_bit);
}
}
void bit_move(void* d, size_t doff, const void* s, size_t soff, size_t n) {
bit_op(d, doff, s, soff, n, [](uint8_t, uint8_t s) { return s; });
}
void bit_xor(void* d, size_t doff, const void* s, size_t soff, size_t n) {
bit_op(d, doff, s, soff, n, [](uint8_t d, uint8_t s) { return d ^ s; });
}
void bit_or(void* d, size_t doff, const void* s, size_t soff, size_t n) {
bit_op(d, doff, s, soff, n, [](uint8_t d, uint8_t s) { return d | s; });
}
void bit_and(void* d, size_t doff, const void* s, size_t soff, size_t n) {
bit_op(d, doff, s, soff, n, [](uint8_t d, uint8_t s) { return d & s; });
}
}
constexpr uint8_t reverse8(uint8_t b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
constexpr std::array<uint8_t, 256> make_reverse8_table() {
std::array<uint8_t, 256> arr = {};
for (uint16_t i = 0; i < 256; ++i) arr[i] = reverse8(static_cast<uint8_t>(i));
return arr;
}
constexpr auto reserve8 = make_reverse8_table();
#define BYTE(b) reserve8[0b##b]
#ifdef _USE_GTEST
#include <gtest/gtest.h>
using namespace Psc;
// 辅助函数:字节数组转十六进制字符串(方便调试)
std::string bytes_to_hex(const std::vector<uint8_t>& v) {
std::ostringstream oss;
for (auto b : v) {
oss << std::hex << std::setw(2) << std::setfill('0') << (int)b;
}
return oss.str();
}
// case 2dest 偏移,src 对齐
TEST(BitMoveTest, DestBitOffset) {
struct Data {
std::vector<uint8_t> dest;
size_t dest_offset;
std::vector<uint8_t> src;
size_t src_offset;
size_t num;
std::vector<uint8_t> expected_move;
std::vector<uint8_t> expected_xor;
std::vector<uint8_t> expected_or;
std::vector<uint8_t> expected_and;
std::string msg;
};
std::vector<Data> list;
// 1. 目标偏移2位,拷贝6位
// 00 00000000
// dest 000000
// src 111100
// xor: 111100
// or: 111100
// and: 000000
Data d1{
{BYTE(00000000), BYTE(00000000)},
2,
{BYTE(11110000), BYTE(00001111)},
0,
6,
{BYTE(00111100), BYTE(00000000)},
// move
{BYTE(00111100), BYTE(00000000)},
// xor (0x3C, 0x00)
{BYTE(00111100), BYTE(00000000)},
// or (0x3C, 0x00)
{BYTE(00000000), BYTE(00000000)},
// and (0x00, 0x00)
"目标偏移2位,拷贝6位"
};
char arr[100];
size_t a = get_mem2hex_size(2, 0);
mem2hex_Ex2(arr, d1.expected_move.data(), 2, false, "");
EXPECT_STREQ(hex2bin(std::string(arr, a)).c_str(), "0011110000000000");
// 2. 目标偏移1位,拷贝9位,跨越目标字节
// 1 000001
// dest 000000000
// src 011111111
// xor: 011111111
// or: 011111111
// and: 000000000
list.push_back({
{BYTE(10000000), BYTE(00000001)},
1,
{BYTE(01111111), BYTE(10000000)},
0,
9,
{BYTE(10111111), BYTE(11000001)},
// move
{BYTE(10111111), BYTE(11000001)},
// xor (0xFE, 0x83)
{BYTE(10111111), BYTE(11000001)},
// or (0xFE, 0x83)
{BYTE(10000000), BYTE(00000001)},
// and (0x01, 0x03)
"目标偏移1位,拷贝9位,跨字节"
});
// 3. 目标偏移4,源偏移3,拷贝8位
// 1100 1010
// dest 00111010
// src 10000000
// xor 10111010
// or 10111010
// and 00000000
list.push_back({
{BYTE(11000011), BYTE(10101010)},
4,
{BYTE(11110000), BYTE(00001111)},
3,
8,
{BYTE(11001000), BYTE(00001010)},
// move
{BYTE(11001011), BYTE(10101010)},
// xor
{BYTE(11001011), BYTE(10101010)},
// or
{BYTE(11000000), BYTE(00001010)},
// and
"目标偏移4,源偏移3,拷贝8位"
});
// 4. 全1拷贝部分,全0目标
// 00000 0000
// dest 0000000
// src 1111111
// xor 1111111
// or 1111111
// and 0000000
list.push_back({
{BYTE(00000000), BYTE(00000000)},
5,
{BYTE(11111111), BYTE(11111111)},
2,
7,
{BYTE(00000111), BYTE(11110000)},
// move
{BYTE(00000111), BYTE(11110000)},
// xor
{BYTE(00000111), BYTE(11110000)},
// or
{BYTE(00000000), BYTE(00000000)},
// and
"全1源,拷贝7位到目标末尾"
});
// 5. 源目标均有内容(交错)
// 110 10011
// dest 01100001
// src 10100101
// xor 11000100
// or 11100101
// and 00100001
list.push_back({
{BYTE(11001100), BYTE(00110011)},
3,
{BYTE(10101010), BYTE(01010101)},
4,
8,
{BYTE(11010100), BYTE(10110011)},
// move
{BYTE(11011000), BYTE(10010011)},
// xor
{BYTE(11011100), BYTE(10110011)},
// or
{BYTE(11000100), BYTE(00110011)},
// and
"目标有内容,源偏移4,拷贝8位"
});
// 6. 源目标完全重叠
// 1011 01
// dest 1001110100
// src 1101111010
// move 1101111010
// xor 0100001110
// or 1101111110
// and 1001110000
list.push_back({
{BYTE(10111001), BYTE(11010001)},
4,
{BYTE(10110111), BYTE(10100101)},
2,
10,
{BYTE(10111101), BYTE(11101001)},
// move
{BYTE(10110100), BYTE(00111001)},
// xor
{BYTE(10111101), BYTE(11111001)},
// or
{BYTE(10111001), BYTE(11000001)},
// and
"目标/源重叠,偏移不同"
});
for (auto& d : list) {
auto dest_move = d.dest;
auto dest_xor = d.dest;
auto dest_or = d.dest;
auto dest_and = d.dest;
bit_move(dest_move.data(), d.dest_offset, d.src.data(), d.src_offset, d.num);
bit_xor(dest_xor.data(), d.dest_offset, d.src.data(), d.src_offset, d.num);
bit_or(dest_or.data(), d.dest_offset, d.src.data(), d.src_offset, d.num);
bit_and(dest_and.data(), d.dest_offset, d.src.data(), d.src_offset, d.num);
EXPECT_EQ(dest_move, d.expected_move) << "move 结果: " << hex2bin(bytes_to_hex(dest_move)) << "\n期望: " <<
hex2bin(bytes_to_hex(d.expected_move)) << "\n" + d.msg;
EXPECT_EQ(dest_xor, d.expected_xor) << "xor 结果: " << bytes_to_hex(dest_xor) << "\n期望: " <<
bytes_to_hex(d.expected_xor) << "\n" + d.msg;
EXPECT_EQ(dest_or, d.expected_or) << "or 结果: " << bytes_to_hex(dest_or) << "\n期望: " <<
bytes_to_hex(d.expected_or) << "\n" + d.msg;
EXPECT_EQ(dest_and, d.expected_and) << "and 结果: " << bytes_to_hex(dest_and) << "\n期望: " <<
bytes_to_hex(d.expected_and) << "\n" + d.msg;
}
}
// 测试二进制到十六进制转换
TEST(Bit_Convert, Bin2Hex) {
std::pmr::string s("11101110");
std::string s2("11101110");
// 检查 bin2hex 的转换结果
EXPECT_EQ(bin2hex(s), "EE"); // 假设 bin2hex("11101110") 应该是 "EE"
EXPECT_EQ(bin2hex(s2), "EE"); // 同样检查 std::string 版本
EXPECT_EQ(bin2hex("11101110"), "EE"); // 直接测试常量字符串
}
TEST(BitOpsLE, WriteAndReadFullByte) {
uint8_t buf[8] = {0};
set_bits(buf, 0, 8, 0xAB); // 小端模式:低位在低bit
EXPECT_EQ(buf[0], 0xAB);
EXPECT_EQ(get_bits(buf, 0, 8), 0xAB);
}
TEST(BitOpsLE, CrossByteWriteAndRead) {
uint8_t buf[8] = {0};
set_bits(buf, 4, 12, 0xF0F); // 写12位,偏移4
EXPECT_EQ(get_bits(buf, 4, 12), 0xF0F);
}
TEST(BitOpsLE, UnalignedBitWriteAndRead) {
uint8_t buf[8] = {0};
set_bits(buf, 5, 10, 0x2AA); // 偏移5位,写10位
EXPECT_EQ(get_bits(buf, 5, 10), 0x2AA);
}
TEST(BitOpsLE, SingleBitWriteAndRead) {
uint8_t buf[8] = {0};
set_bits(buf, 10, 1, 1);
EXPECT_EQ(get_bits(buf, 10, 1), 1);
set_bits(buf, 10, 1, 0);
EXPECT_EQ(get_bits(buf, 10, 1), 0);
}
TEST(BitOpsLE, WriteAndReadFullUint64) {
uint8_t buf[8] = {0};
set_bits(buf, 0, 64, 0x123456789ABCDEF0ULL);
EXPECT_EQ(get_bits(buf, 0, 64), 0x123456789ABCDEF0ULL);
}
TEST(BitOpsLE, OverwriteZeroBits) {
uint8_t buf[8];
std::memset(buf, 0xFF, sizeof(buf));
set_bits(buf, 16, 16, 0x0000);
EXPECT_EQ(get_bits(buf, 16, 16), 0x0000);
// 其它位应保持原值
for (size_t i = 0; i < 2; ++i)
EXPECT_EQ(buf[i], 0xFF);
for (size_t i = 4; i < 8; ++i)
EXPECT_EQ(buf[i], 0xFF);
}
TEST(BitOpsLE, AllZeroAndAllOne) {
uint8_t buf[8] = {0};
set_bits(buf, 0, 64, 0xFFFFFFFFFFFFFFFFULL);
EXPECT_EQ(get_bits(buf, 0, 64), 0xFFFFFFFFFFFFFFFFULL);
set_bits(buf, 0, 64, 0x0ULL);
EXPECT_EQ(get_bits(buf, 0, 64), 0x0ULL);
}
#else
#endif