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
#pragma once #include <cstdint> #include <string> namespace cutl { /** * @brief Endianness type. * */ enum class endian { /** little endian */ little, /** big endian */ big, }; /** * @brief Get the program endianness. * * @return endian the program endianness. */ endian endian_type(); /** * @brief Byteswap a 16-bit value. * * @param value the value to byteswap. * @return uint16_t the byteswapped value. */ uint16_t byteswap(uint16_t value); /** * @brief Byteswap a 32-bit value. * * @param value the value to byteswap. * @return uint32_t the byteswapped value. */ uint32_t byteswap(uint32_t value); /** * @brief Byteswap a 64-bit value. * * @param value the value to byteswap. * @return uint64_t the byteswapped value. */ uint64_t byteswap(uint64_t value); /** * @brief Byteswap an array of bytes. * * @param data the array of bytes to byteswap. * @param size the size of the array. */ void byteswap(uint8_t *data, uint32_t size); } // namespace cutl
3. sysutil.cpp
#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; } } } // namespace cutl
4. 测试代码
#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. 运行结果
---------------------------------------------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。
本文由博客一文多发平台 OpenWrite 发布!
标签:
C++
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战