C++系统相关操作7 - 判断系统大小端&大小端的数据转换
1. 关键词 关键词:
C++ 大端 小端 数据转换 跨平台
大小端的定义:
大端(Big Endian)和小端(Little Endian)是指在计算机内存中存储多字节数据类型的字节顺序。以下是它们的区别:
大小端
定义
区别
示例(0x1234)
大端
数据的最高有效字节(Most Significant Byte, MSB)存储在内存的最低地址,而最低有效字节(Least Significant Byte, LSB)存储在内存的最高地址。
最高有效字节存储在最低地址 又称:网络字节序
内存地址: 高 -> 低 存储内容: 0x34 0x12
小端
数据的最低有效字节(Least Significant Byte, LSB)存储在内存的最低地址,而最高有效字节(Most Significant Byte, MSB)存储在内存的最高地址。
最低有效字节存储在最低地址 又称:主机字节序
内存地址: 高 -> 低 存储内容: 0x12 0x34
实现原理:
通过高低地址位的数据判断大端或小端。
应用场景:
网络传输协议中,大端和小端的字节序不同,需要转换为网络字节序。
不同平台的数据交换,需要转换为统一的字节序。
2. sysutil.h 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #pragma once #include <cstdint> #include <string> namespace cutl{ enum class endian { little, big, }; endian endian_type () ; uint16_t byteswap (uint16_t value) ; uint32_t byteswap (uint32_t value) ; uint64_t byteswap (uint64_t value) ; void byteswap (uint8_t *data, uint32_t size) ; }
3. sysutil.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 #include <map> #include <iostream> #include <strutil.h> #include <cstdlib> #include "sysutil.h" #include "inner/logger.h" #include "inner/system_util.h" #include "inner/filesystem.h" namespace cutl{ endian endian_type () { int a = 1 ; int *p = &a; uint8_t *pBtye = (uint8_t *)p; if (*pBtye == 1 ) { return endian::little; } else { return endian::big; } } uint16_t byteswap (uint16_t value) { auto data = (uint8_t *)(&value); byteswap (data, 2 ); return value; } uint32_t byteswap (uint32_t value) { auto data = (uint8_t *)(&value); byteswap (data, 4 ); return value; } uint64_t byteswap (uint64_t value) { auto data = (uint8_t *)(&value); byteswap (data, 8 ); return value; } void byteswap (uint8_t *data, uint32_t size) { uint32_t n = size / 2 ; for (uint32_t i = 0 ; i < n; i++) { uint8_t temp = data[i]; data[i] = data[size - i - 1 ]; data[size - i - 1 ] = temp; } } }
4. 测试代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #include "common.hpp" #include "sysutil.h" void TestEndian () { PrintSubTitle ("TestEndian" ); if (cutl::endian_type () == cutl::endian::little) { std::cout << "OS endianness: little endian" << std::endl; } else { std::cout << "OS endianness: big endian" << std::endl; } uint16_t a = 0x1234 ; std::cout << "byteswap for a: " << cutl::to_hex (cutl::byteswap (a)) << std::endl; uint32_t b = 0x12345678 ; std::cout << "byteswap for b: " << cutl::to_hex (cutl::byteswap (b)) << std::endl; uint64_t c = 0x123456789ABCDEF0 ; std::cout << "byteswap for c: " << cutl::to_hex (cutl::byteswap (c)) << std::endl; uint8_t bytes[] = {0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0a , 0x0b , 0x0c , 0x0d , 0x0e , 0x0f , 0x10 }; cutl::byteswap (bytes, 16 ); std::cout << "byteswap for bytes: " << cutl::to_hex (bytes, 16 ) << std::endl; }
5. 运行结果 1 2 3 4 5 6 ---------------------------------------------TestEndian--------------------------------------------- OS endianness: little endian byteswap for a: 3412 byteswap for b: 78563412 byteswap for c: F0DEBC9A78563412 byteswap for bytes: 10 0F 0E 0D 0C 0B 0A 09 08 07 06 05 04 03 02 01
6. 源码地址 更多详细代码,请查看本人写的C++ 通用工具库: common_util , 本项目已开源,代码简洁,且有详细的文档和Demo。