한글 "가나" 를 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 */
링크
'Engineering > Etc' 카테고리의 다른 글
git local 저장 간편 사용법 (0) | 2013.03.13 |
---|---|
strtok() 대신 strsep() 를 사용하자. (0) | 2012.11.30 |
stack 깨질때 gcc compile 옵션 (0) | 2012.07.10 |
wordpress 설치시 ftp 업데이트를 안전하게 하기위해 ftps 사용 (0) | 2012.05.15 |
대용량 텍스트 파일 내용 변경하기 (0) | 2012.04.19 |