字节序(Byte Order)是指计算机中多字节数据类型(如整型、浮点型等)在内存中存储的顺序。
常见的字节序有两种:
字节序的选择对于数据的解析和传输都非常重要。如果发送方和接收方的字节序不一致,就会导致数据解析错误。因此,在进行跨平台数据交互时,需要明确指定和处理字节序,以确保数据的正确传输和解析。
注:可以在代码中采取条件编译,根据字节序的不同选择不同的成员顺序,以适应不同的字节序要求。这样可以保证在不同的平台上都能正确地解析数据。
注:不同的处理器架构和操作系统可能采用不同的字节序。例如,x86架构的处理器通常采用小端序,而网络协议常使用大端序。因此,在进行跨平台数据交互时,需要注意字节序的转换和处理,以确保数据的正确传输和解析。
我们定义了两个函数 bigEndianToLittleEndian16 和 bigEndianToLittleEndian32,用于将大端序的 16 位整数和 32 位整数转换为小端序。通过位操作和移位运算,我们可以将字节的顺序进行转换。
#include
#include
#include
// 将一个 16 位整数从大端序转换为小端序
uint16_t bigEndian2LittleEndian16(uint16_t value)
{
return (value >> 8) | (value << 8);
}
// 将一个 32 位整数从大端序转换为小端序
uint32_t bigEndian2LittleEndian32(uint32_t value)
{
return ((value & 0xFF000000) >> 24) | ((value & 0x00FF0000) >> 8) | ((value & 0x0000FF00) << 8) | ((value & 0x000000FF) << 24);
}
int main()
{
uint16_t bigEndian16 = 0x1234;
uint32_t bigEndian32 = 0x12345678;
uint16_t littleEndian16 = bigEndian2LittleEndian16(bigEndian16);
uint32_t littleEndian32 = bigEndian2LittleEndian32(bigEndian32);
std::cout << "Big Endian 16: 0x" << std::hex << bigEndian16 << std::endl;
std::cout << "Little Endian 16: 0x" << std::hex << littleEndian16 << std::endl;
std::cout << "Big Endian 32: 0x" << std::hex << bigEndian32 << std::endl;
std::cout << "Little Endian 32: 0x" << std::hex << littleEndian32 << std::endl;
return 0;
}
对应的小端序转为大端序的函数为:
// 将一个 16 位整数从小端序转换为大端序
uint16_t littleEndianToBigEndian16(uint16_t value) {
return (value >> 8) | (value << 8);
}
// 将一个 32 位整数从小端序转换为大端序
uint32_t littleEndianToBigEndian32(uint32_t value) {
return ((value & 0xFF000000) >> 24) | ((value & 0x00FF0000) >> 8) |
((value & 0x0000FF00) << 8) | ((value & 0x000000FF) << 24);
}
boost::endian
库进行转换#include
#include
int main()
{
uint16_t bigEndian16 = 0x1234;
uint32_t bigEndian32 = 0x12345678;
uint16_t littleEndian16 = boost::endian::native_to_little(bigEndian16);
uint32_t littleEndian32 = boost::endian::native_to_little(bigEndian32);
std::cout << "Big Endian 16: 0x" << std::hex << bigEndian16 << std::endl;
std::cout << "Little Endian 16: 0x" << std::hex << littleEndian16 << std::endl;
std::cout << "Big Endian 32: 0x" << std::hex << bigEndian32 << std::endl;
std::cout << "Little Endian 32: 0x" << std::hex << littleEndian32 << std::endl;
return 0;
}
对应的小端序转为大端序的示例为:
uint16_t bigEndian16 = boost::endian::native_to_big(littleEndian16);
uint32_t bigEndian32 = boost::endian::native_to_big(littleEndian32);
Poco::ByteOrder
类进行转换#include
#include
int main()
{
uint16_t bigEndian16 = 0x1234;
uint32_t bigEndian32 = 0x12345678;
uint16_t littleEndian16 = Poco::ByteOrder::flipBytes(bigEndian16);
uint32_t littleEndian32 = Poco::ByteOrder::flipBytes(bigEndian32);
std::cout << "Big Endian 16: 0x" << std::hex << bigEndian16 << std::endl;
std::cout << "Little Endian 16: 0x" << std::hex << littleEndian16 << std::endl;
std::cout << "Big Endian 32: 0x" << std::hex << bigEndian32 << std::endl;
std::cout << "Little Endian 32: 0x" << std::hex << littleEndian32 << std::endl;
return 0;
}
对应的小端序转为大端序的示例为:
uint16_t bigEndian16 = Poco::ByteOrder::flipBytes(littleEndian16);
uint32_t bigEndian32 = Poco::ByteOrder::flipBytes(littleEndian32);
对于非整数类型(如字符串、结构体等),字节序的转换需要更加谨慎和具体情况而定。一般情况下,字符串的字节序转换需要考虑字符编码的影响。
如果你需要对字符串进行字节序转换,可以将字符串转换为字节数组,然后对字节数组进行字节序转换,最后再将字节数组转换回字符串。
#include
#include
#include
#include
// 将字符串转换为字节数组std::vector
std::vector<uint8_t> string2Bytes(const std::string& str){
// str.begin() 返回一个迭代器,指向字符串 str 的起始位置,即第一个字符处。 str.end() 返回一个迭代器,指向字符串 str 结束位置的下一个位置,即字符串末尾之后的位置。在 C++ 中,字符串是一种容器,可以使用迭代器来遍历其中的字符。
// 使用了迭代器来遍历字符串中的每个字符,并将每个字符转换为 uint8_t 类型后添加到 std::vector 容器中。
std::vector<uint8_t> bytes(str.begin(), str.end());
return bytes;
}
// 将字节数组转换为字符串
std::string bytes2String(const std::vector<uint8_t>& bytes){
std::string str(bytes.begin(), bytes.end());
return str;
}
// 对字节数组进行字节序转换
void flipBytes(std::vector<uint8_t>& bytes){
std::reverse(bytes.begin(), bytes.end());
}
int main()
{
std::string str = "Hello, World!";
// 将字符串转换为字节数组
std::vector<uint8_t> bytes = string2Bytes(str);
// 对字节数组进行字节序转换
flipBytes(bytes);
// 将字节数组转换为字符串
std::string convertedStr = bytes2String(bytes);
std::cout << "Original string: " << str << std::endl;
std::cout << "Converted string: " << convertedStr << std::endl;
return 0;
}