- 1. 關鍵詞
- 2. sysutil.h
- 3. sysutil.cpp
- 4. 測試程式碼
- 5. 執行結果
- 6. 原始碼地址
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 釋出!