Initial commit

This commit is contained in:
2026-06-16 10:56:40 +08:00
commit d2f95e0e27
2047 changed files with 619063 additions and 0 deletions
+755
View File
@@ -0,0 +1,755 @@
#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