본문 바로가기

TroubleShooting/Etc

OS mac 와 linux 에서 hexdump 비교

728x90

한글 "가나" 를 UTF-8 인코딩으로 저장하고, iconv 테스트를 진행하면서 mac 과 linux 에서 hexdump 옵션에 따라 값이 다르게 표시되는 것을 발견했다. 


둘다 intel CPU, 64 bit 환경이다. 물론 둘다 byte ordering 은 little endian 이다. 

"가" 의  unicode 값은 0xAC00,  "나" 의 unicode값은 0xB098 이다.


$ cat "가나" > cc

$ ls -la cc

-rw-rw-r-- 1 firstboos firstboos 7 Oct 23 15:52 cc

===> 7byte 이기 때문에 UTF-8 로 저장된게 맞음. 마지막 LF 가 1byte.


$ iconv -f utf-8 -t ucs-2 cc > uu

$ ls -la uu

-rw-rw-r-- 1 firstboos firstboos 6 Oct 23 16:27 u3

====> 6 byte unicode. 마지막 LF 가 2 byte.


* mac

$ hexdump tt

0000000 ac00 b098 000a                         

0000006

$ hexdump -x uu

0000000    ac00    b098    000a                                        

0000006


* linux

$ hexdump uu

0000000 ac 00 b0 98 00 0a                              

0000006

$ hexdump -x uu

0000000    00ac    98b0    0a00                                

0000006


그러나, 프로그램 코딩을 하다보니 처리가 다르다는 것을 발견하였다.

* mac

const char src[] = { 0xac, 0x00, 0xb0, 0x98, 0x00, 0x0a };

char dst[1024];


 if (ucs2tomb(src, dst, sizeof(src)) > 0 )

        printf( "RESULT = %s(%d)\n", dst, strlen(dst) );


* linux

const char src[] = { 0x00, 0xac, 0x98, 0xb0, 0x0a, 0x00 };

char dst[1024];


 if (ucs2tomb(src, dst, sizeof(src)) > 0 )

        printf( "RESULT = %s(%d)\n", dst, strlen(dst) );


 둘다 "가나" 에 해당하는 유니코드 인코딩을 UTF-8 로 변환해서 출력하는 코드인데,  mac 에서는 big-endian 표현법으로 해야지 정상적으로 출력된다.


혹시나해서 endian define 값이 시스템 헤더파일 어디에 정의되어 있는지 확인해보았다.

* mac

/usr/include/i386/endian.h 에서 __DARWIN_BYTE_ORDER 을 __DARWIN_LITTLE_ENDIAN 이라고 정의(define)하고 있다.

#ifndef _I386__ENDIAN_H_

#define _I386__ENDIAN_H_


#include <sys/cdefs.h>

/*

 * Define _NOQUAD if the compiler does NOT support 64-bit integers.

 */

/* #define _NOQUAD */


/*

 * Define the order of 32-bit words in 64-bit words.

 */

#define _QUAD_HIGHWORD 1

#define _QUAD_LOWWORD 0


/*

 * Definitions for byte order, according to byte significance from low

 * address to high.

 */

#define __DARWIN_LITTLE_ENDIAN  1234    /* LSB first: i386, vax */

#define __DARWIN_BIG_ENDIAN 4321    /* MSB first: 68000, ibm, net */

#define __DARWIN_PDP_ENDIAN 3412    /* LSB first in word, MSW first in long */


#define __DARWIN_BYTE_ORDER __DARWIN_LITTLE_ENDIAN


#if defined(KERNEL) || (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))


#define LITTLE_ENDIAN   __DARWIN_LITTLE_ENDIAN

#define BIG_ENDIAN  __DARWIN_BIG_ENDIAN

#define PDP_ENDIAN  __DARWIN_PDP_ENDIAN


#define BYTE_ORDER  __DARWIN_BYTE_ORDER


#include <sys/_endian.h>


#endif /* defined(KERNEL) || (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)) */

#endif /* !_I386__ENDIAN_H_ */ 


* linux

/usr/include/bits/endian.h 에서 __BYTE_ORDER 값이 __LITTLE_ENDIAN  으로 정의(define) 하고 있다.

/* x86_64 is little-endian.  */


#ifndef _ENDIAN_H

# error "Never use <bits/endian.h> directly; include <endian.h> instead."

#endif


#define __BYTE_ORDER __LITTLE_ENDIAN


/usr/include/endian.h 에서 

#ifndef _ENDIAN_H

#define _ENDIAN_H   1


#include <features.h>


/* Definitions for byte order, according to significance of bytes,

   from low addresses to high addresses.  The value is what you get by

   putting '4' in the most significant byte, '3' in the second most

   significant byte, '2' in the second least significant byte, and '1'

   in the least significant byte, and then writing down one digit for

   each byte, starting with the byte at the lowest address at the left,

   and proceeding to the byte with the highest address at the right.  */


#define __LITTLE_ENDIAN 1234

#define __BIG_ENDIAN    4321

#define __PDP_ENDIAN    3412


/* This file defines `__BYTE_ORDER' for the particular machine.  */

#include <bits/endian.h>


/* Some machines may need to use a different endianness for floating point

   values.  */

#ifndef __FLOAT_WORD_ORDER

# define __FLOAT_WORD_ORDER __BYTE_ORDER

#endif


#ifdef  __USE_BSD

# define LITTLE_ENDIAN  __LITTLE_ENDIAN

# define BIG_ENDIAN __BIG_ENDIAN

# define PDP_ENDIAN __PDP_ENDIAN

# define BYTE_ORDER __BYTE_ORDER

#endif


#if __BYTE_ORDER == __LITTLE_ENDIAN

# define __LONG_LONG_PAIR(HI, LO) LO, HI

#elif __BYTE_ORDER == __BIG_ENDIAN

# define __LONG_LONG_PAIR(HI, LO) HI, LO

#endif


#endif  /* endian.h */


링크

http://en.wikipedia.org/wiki/Endianness

http://titus.uni-frankfurt.de/unicode/unitestx.htm