ํƒœ๊ทธ ๋ณด๊ด€๋ฌผ: c++

c++

C ++์—์„œ ๋น… ์—”๋””์•ˆ๊ณผ ๋ฆฌํ‹€ ์—”๋””์•ˆ ๊ฐ’์„ ์–ด๋–ป๊ฒŒ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๊นŒ? ๋ณ€ํ™˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋„คํŠธ์›Œํ‚น๊ณผ

C ++์—์„œ ๋น… ์—”๋””์•ˆ๊ณผ ๋ฆฌํ‹€ ์—”๋””์•ˆ ๊ฐ’์„ ์–ด๋–ป๊ฒŒ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๊นŒ?

ํŽธ์ง‘ : ๋ช…ํ™•์„ฑ์„ ์œ„ํ•ด ์ด์ง„ ๋ฐ์ดํ„ฐ (๋ฐฐ์ • ๋ฐ€๋„ ๋ถ€๋™ ์†Œ์ˆ˜์  ๊ฐ’ ๋ฐ 32 ๋น„ํŠธ ๋ฐ 64 ๋น„ํŠธ ์ •์ˆ˜)๋ฅผ ํ•œ CPU ์•„ํ‚คํ…์ฒ˜์—์„œ ๋‹ค๋ฅธ CPU ์•„ํ‚คํ…์ฒ˜๋กœ ๋ณ€ํ™˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋„คํŠธ์›Œํ‚น๊ณผ ๊ด€๋ จ์ด ์—†์œผ๋ฏ€๋กœ ntoh () ๋ฐ ์ด์™€ ์œ ์‚ฌํ•œ ํ•จ์ˆ˜๋Š” ์—ฌ๊ธฐ์„œ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ํŽธ์ง‘ # 2 : ๋‚ด๊ฐ€ ๋ฐ›์•„ ๋“ค์ธ ๋Œ€๋‹ต์€ ๋‚ด๊ฐ€ ํƒ€๊ฒŸํŒ…ํ•˜๋Š” ์ปดํŒŒ์ผ๋Ÿฌ์— ์ง์ ‘ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค (๊ทธ๋ž˜์„œ ๋‚ด๊ฐ€ ์„ ํƒํ•œ ์ด์œ ). ๊ทธ๋Ÿฌ๋‚˜ ์—ฌ๊ธฐ์—๋Š” ๋งค์šฐ ํ›Œ๋ฅญํ•˜๊ณ  ์ด์‹์„ฑ์ด ์ข‹์€ ๋‹ค๋ฅธ ๋‹ต๋ณ€์ด ์žˆ์Šต๋‹ˆ๋‹ค.



๋‹ต๋ณ€

๋‹น์‹ ์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ Visual C ++๋ฅผ ๋‹ค์Œ์„ ์ˆ˜ํ–‰ : ๋‹น์‹ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์„ intrin.h ํฌํ•จ ์ „ํ™” :

16 ๋น„ํŠธ ์ˆซ์ž์˜ ๊ฒฝ์šฐ :

unsigned short _byteswap_ushort(unsigned short value);

32 ๋น„ํŠธ ์ˆซ์ž์˜ ๊ฒฝ์šฐ :

unsigned long _byteswap_ulong(unsigned long value);

64 ๋น„ํŠธ ์ˆซ์ž์˜ ๊ฒฝ์šฐ :

unsigned __int64 _byteswap_uint64(unsigned __int64 value);

8 ๋น„ํŠธ ์ˆซ์ž (๋ฌธ์ž)๋Š” ๋ณ€ํ™˜ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ์ด๋“ค์€ ๋ถ€ํ˜ธ์—†๋Š” ์ •์ˆ˜์— ๋Œ€ํ•ด์„œ๋งŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

float ๋ฐ double์˜ ๊ฒฝ์šฐ ํ˜ธ์ŠคํŠธ ์‹œ์Šคํ…œ์— ๋ฐ”์ดํŠธ ์ˆœ์„œ๊ฐ€ ์žˆ๊ฑฐ๋‚˜ ์—†์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ผ๋ฐ˜ ์ •์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ๋น… ์—”๋””์•ˆ ๋จธ์‹ ์—์„œ ๋ฆฌํ‹€ ์—”๋””์•ˆ ์ˆ˜๋ ˆ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ทธ ๋ฐ˜๋Œ€๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์ปดํŒŒ์ผ๋Ÿฌ๋„ ๋น„์Šทํ•œ ๋ณธ์งˆ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด GCC ์—์„œ๋Š” ์—ฌ๊ธฐ์— ์„ค๋ช… ๋œ๋Œ€๋กœ ์ผ๋ถ€ ๋‚ด์žฅ์„ ์ง์ ‘ ํ˜ธ์ถœ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค .

uint32_t __builtin_bswap32 (uint32_t x)
uint64_t __builtin_bswap64 (uint64_t x)

(๋ฌด์—‡์„ ํฌํ•จ ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค). Afaik bits.h๋Š” gcc ์ค‘์‹ฌ์ด ์•„๋‹Œ ๋ฐฉ์‹์œผ๋กœ ๋™์ผํ•œ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.

16 ๋น„ํŠธ ์Šค์™‘์€ ๋น„ํŠธ ํšŒ์ „์ž…๋‹ˆ๋‹ค.

๋กค๋ง ๋Œ€์‹  ๋‚ด์žฅ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ตœ์ƒ์˜ ์„ฑ๋Šฅ๊ณผ ์ฝ”๋“œ ๋ฐ€๋„๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๋‹ต๋ณ€

๊ฐ„๋‹จํžˆ ๋งํ•ด์„œ:

#include <climits>

template <typename T>
T swap_endian(T u)
{
    static_assert (CHAR_BIT == 8, "CHAR_BIT != 8");

    union
    {
        T u;
        unsigned char u8[sizeof(T)];
    } source, dest;

    source.u = u;

    for (size_t k = 0; k < sizeof(T); k++)
        dest.u8[k] = source.u8[sizeof(T) - k - 1];

    return dest.u;
}

์‚ฌ์šฉ๋ฒ• : swap_endian<uint32_t>(42).


๋‹ต๋ณ€

์—์„œ ๋ฐ”์ดํŠธ ์ฃผ๋ฌธ ์ฐฉ์˜ค ๋กญ ํŒŒ์ดํฌ์— ์˜ํ•ด :

๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์— ๋ฆฌํ‹€ ์—”๋””์•ˆ ์ธ์ฝ”๋”ฉ ๋œ 32 ๋น„ํŠธ ์ •์ˆ˜๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ • ํ•ด ๋ด…์‹œ๋‹ค. ๋ถ€ํ˜ธ์—†๋Š” ๋ฐ”์ดํŠธ๋ฅผ ๊ฐ€์ •ํ•˜์—ฌ ์ถ”์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

i = (data[0]<<0) | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);

๋น… ์—”๋””์•ˆ์ด๋ผ๋ฉด ์ถ”์ถœ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

i = (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);

TL; DR : ํ”Œ๋žซํผ ๊ธฐ๋ณธ ์ˆœ์„œ์— ๋Œ€ํ•ด ๊ฑฑ์ •ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค . ์นด์šดํŠธ๋Š” ๋ชจ๋‘ ์ฝ๊ณ ์žˆ๋Š” ์ŠคํŠธ๋ฆผ์˜ ๋ฐ”์ดํŠธ ์ˆœ์„œ์ด๋ฉฐ ์ž˜ ์ •์˜๋˜์–ด ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

์ฐธ๊ณ  : ์ฃผ์„์—์„œ ๋ช…์‹œ ์  ์œ ํ˜• ๋ณ€ํ™˜์ด์—†๋Š” ๊ฒƒ์œผ๋กœ ์–ธ๊ธ‰๋˜์—ˆ์œผ๋ฏ€๋กœ ๋˜๋Š” data์˜ ๋ฐฐ์—ด์ด์–ด์•ผํ•ฉ๋‹ˆ๋‹ค . ์‚ฌ์šฉ ๋˜๋Š” (์„œ๋ช… ๊ฒฝ์šฐ)๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค ์ •์ˆ˜๋กœ ์Šน์ง„ํ•˜๊ณ  ์ž ์žฌ์  UB์ด๋‹ค ๋ถ€ํ˜ธ ๋น„ํŠธ์— 1์„ ์ด๋™.unsigned charuint8_tsigned charchardata[x]data[x] << 24


๋‹ต๋ณ€

๋„คํŠธ์›Œํฌ / ํ˜ธ์ŠคํŠธ ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

ntohl() //Network to Host byte order (Long)
htonl() //Host to Network byte order (Long)

ntohs() //Network to Host byte order (Short)
htons() //Host to Network byte order (Short)

๋‹ค๋ฅธ ์ด์œ ๋กœ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ ์—ฌ๊ธฐ์— ์ œ๊ณต๋œ byte_swap ์†”๋ฃจ์…˜ ์ค‘ ํ•˜๋‚˜๊ฐ€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.


๋‹ต๋ณ€

๋‚˜๋Š”์ด ๊ฒŒ์‹œ๋ฌผ์—์„œ ๋ช‡ ๊ฐ€์ง€ ์ œ์•ˆ์„ํ•˜๊ณ  ์ด๊ฒƒ์„ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•ด ํ•จ๊ป˜ ๋ชจ์•˜์Šต๋‹ˆ๋‹ค.

#include <boost/type_traits.hpp>
#include <boost/static_assert.hpp>
#include <boost/detail/endian.hpp>
#include <stdexcept>

enum endianness
{
    little_endian,
    big_endian,
    network_endian = big_endian,

    #if defined(BOOST_LITTLE_ENDIAN)
        host_endian = little_endian
    #elif defined(BOOST_BIG_ENDIAN)
        host_endian = big_endian
    #else
        #error "unable to determine system endianness"
    #endif
};

namespace detail {

template<typename T, size_t sz>
struct swap_bytes
{
    inline T operator()(T val)
    {
        throw std::out_of_range("data size");
    }
};

template<typename T>
struct swap_bytes<T, 1>
{
    inline T operator()(T val)
    {
        return val;
    }
};

template<typename T>
struct swap_bytes<T, 2>
{
    inline T operator()(T val)
    {
        return ((((val) >> 8) & 0xff) | (((val) & 0xff) << 8));
    }
};

template<typename T>
struct swap_bytes<T, 4>
{
    inline T operator()(T val)
    {
        return ((((val) & 0xff000000) >> 24) |
                (((val) & 0x00ff0000) >>  8) |
                (((val) & 0x0000ff00) <<  8) |
                (((val) & 0x000000ff) << 24));
    }
};

template<>
struct swap_bytes<float, 4>
{
    inline float operator()(float val)
    {
        uint32_t mem =swap_bytes<uint32_t, sizeof(uint32_t)>()(*(uint32_t*)&val);
        return *(float*)&mem;
    }
};

template<typename T>
struct swap_bytes<T, 8>
{
    inline T operator()(T val)
    {
        return ((((val) & 0xff00000000000000ull) >> 56) |
                (((val) & 0x00ff000000000000ull) >> 40) |
                (((val) & 0x0000ff0000000000ull) >> 24) |
                (((val) & 0x000000ff00000000ull) >> 8 ) |
                (((val) & 0x00000000ff000000ull) << 8 ) |
                (((val) & 0x0000000000ff0000ull) << 24) |
                (((val) & 0x000000000000ff00ull) << 40) |
                (((val) & 0x00000000000000ffull) << 56));
    }
};

template<>
struct swap_bytes<double, 8>
{
    inline double operator()(double val)
    {
        uint64_t mem =swap_bytes<uint64_t, sizeof(uint64_t)>()(*(uint64_t*)&val);
        return *(double*)&mem;
    }
};

template<endianness from, endianness to, class T>
struct do_byte_swap
{
    inline T operator()(T value)
    {
        return swap_bytes<T, sizeof(T)>()(value);
    }
};
// specialisations when attempting to swap to the same endianess
template<class T> struct do_byte_swap<little_endian, little_endian, T> { inline T operator()(T value) { return value; } };
template<class T> struct do_byte_swap<big_endian,    big_endian,    T> { inline T operator()(T value) { return value; } };

} // namespace detail

template<endianness from, endianness to, class T>
inline T byte_swap(T value)
{
    // ensure the data is only 1, 2, 4 or 8 bytes
    BOOST_STATIC_ASSERT(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8);
    // ensure we're only swapping arithmetic types
    BOOST_STATIC_ASSERT(boost::is_arithmetic<T>::value);

    return detail::do_byte_swap<from, to, T>()(value);
}

๋‹ต๋ณ€

๋น… ์—”๋””์•ˆ์—์„œ ๋ฆฌํ‹€ ์—”๋””์•ˆ์œผ๋กœ๊ฐ€๋Š” ์ ˆ์ฐจ๋Š” ๋ฆฌํ‹€ ์—”๋””์•ˆ์—์„œ ๋น… ์—”๋””์•ˆ์œผ๋กœ๊ฐ€๋Š” ์ ˆ์ฐจ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ์ œ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

void swapByteOrder(unsigned short& us)
{
    us = (us >> 8) |
         (us << 8);
}

void swapByteOrder(unsigned int& ui)
{
    ui = (ui >> 24) |
         ((ui<<8) & 0x00FF0000) |
         ((ui>>8) & 0x0000FF00) |
         (ui << 24);
}

void swapByteOrder(unsigned long long& ull)
{
    ull = (ull >> 56) |
          ((ull<<40) & 0x00FF000000000000) |
          ((ull<<24) & 0x0000FF0000000000) |
          ((ull<<8) & 0x000000FF00000000) |
          ((ull>>8) & 0x00000000FF000000) |
          ((ull>>24) & 0x0000000000FF0000) |
          ((ull>>40) & 0x000000000000FF00) |
          (ull << 56);
}

๋‹ต๋ณ€

BSWAP๋ผ๋Š” ์กฐ๋ฆฝ ๋ช…๋ น์ด ์žˆ์œผ๋ฉฐ, ์Šค์™‘์„ ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ์ˆ˜ํ–‰ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—์„œ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค .

Visual Studio ๋˜๋Š”๋ณด๋‹ค ์ •ํ™•ํ•˜๊ฒŒ๋Š” Visual C ++ ๋Ÿฐํƒ€์ž„ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š”์ด๋ฅผ์œ„ํ•œ ํ”Œ๋žซํผ ๋‚ด์žฅ ๊ธฐ๋Šฅ์ด _byteswap_ushort(), _byteswap_ulong(), and _byteswap_int64()์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํ”Œ๋žซํผ์—์„œ๋„ ๋น„์Šทํ•ด์•ผํ•˜์ง€๋งŒ ํ”Œ๋žซํผ์ด ๋ฌด์—‡์ธ์ง€ ์•Œ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.


์ด ๊ธ€์€ C++ ์นดํ…Œ๊ณ ๋ฆฌ์— ๋ถ„๋ฅ˜๋˜์—ˆ๊ณ  , ํƒœ๊ทธ๊ฐ€ ์žˆ์œผ๋ฉฐ ๋‹˜์— ์˜ํ•ด ์— ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.