일본웹을 작업할 일이 생겼다.
일본 웹은 자기마음대로(^^ EUC-JP, SHIFT_JIS등)였다.
둘 사이의 연동을 위하여 처음에는 php의 iconv함수를 사용하였지만 만만치 않은 일이였다.
잘 convert되지도 않았다.
그래서 C언어를 통하여 문자셋 변환을 시도했고..
수 많은 헛짓(?)을 통하여 방법을 알아냈다.
테스트 소스는 다음과 같다.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <iconv.h>
#define ICONV_BYTES(a) ((a)*6+1)
char *convert(const char * str, const char * to, const char * from)
{
iconv_t to_utf;
if ((to_utf = iconv_open(to, from)) == (iconv_t) -1) {
utf8_error:
fprintf(stderr, "convert %s from %s to %s failed.\n", str, from, to);
iconv_close(to_utf);
return NULL;
} else {
size_t in_bytes = strlen(str), last_bytes;
char *out = (char *) malloc(ICONV_BYTES(in_bytes));
char *outp = out;
size_t out_bytes = ICONV_BYTES(in_bytes);
do {
int n;
last_bytes = in_bytes;
n = iconv(to_utf, (char **)&str, &in_bytes, &outp, &out_bytes);
if (n < 0){
if( errno == EILSEQ || errno == EINVAL ){
str++; // skip broken byte
in_bytes--;
} else {
goto utf8_error;
}
}
} while (in_bytes > 0 && in_bytes < last_bytes);
iconv_close(to_utf);
*outp = '\0';
return out;
}
}
void encoding(char *dest, unsigned char *source)
{
int len=0,i=0;
char temp[20];
len=strlen(source);
for(i=0;i {
sprintf(temp,"%%%2x",source[i]);
if (temp[1]<'0' || temp[1]>'9') temp[1] -= 32;
if (temp[2]<'0' || temp[2]>'9') temp[2] -= 32;
if (i==0) strcpy(dest,temp);
else strcat(dest,temp);
}
}
int main(int argc, char *argv)
{
//일본어 처리를 위하여//
char *query ="システム";
char encoding_dest[100];
printf("query = [%s]\n", query);
query=convert(query, "SHIFT_JIS", "EUC-KR");
//query=convert(query, "UTF-8", "EUC-KR");
printf("convert = [%s]\n", query);
memset(encoding_dest ,0x00, sizeof(encoding_dest));
encoding(encoding_dest, query);
query = encoding_dest;
printf("complete query = [%s]\n", query);
//일본어 처리 끝//
//システム
//utf-8 = %E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0
//SHIFT_JIS = %83%56%83%58%83%65%83%80
return 0;
}