java 와 C 간의 인코딩 문제...
안녕하세요..
제목과 같이 인코딩 문제로 골머리를 썩고 있습니다.
다름이 아니라.
C는 한글을 2byte 로 인식하고 있습니다
그런데 자바는 유니코드로서 1로 인식하고 있습니다.
예를 들어..
c 일 경우
char *str = "안녕하세요";
strlen(str) => 하면 정수로 10입니다.
그럼 자바일 경우
String str = "안녕하세요";
str.length() => 를 하면 5입니다.
----------------------------------------------------------------------------
아래를 볼때
다음과 같이 C 서버가 java 클라이언트에게
13 byte (주민번호) + 10byte (이름) + 11byte (전화번호)
이렇게 보낼때
java 클라이언트는
데이터를 바이트로 읽어서
String str = new String(byteBuffer)
이런식으로 서버에서 보낸 데이터를 str에 저장합니다.
문제는 여기서 서버가 보낸 각각의 데이터를 각각
String p_num = str.substring(0, 13);
String name = str.substring(13, 10);
String tel_num = str.substring(23, 11);
이렇게 입력한다고 할때..
중간에 있는 이름을 10 byte만큼 읽을려고 하지만
substring 에서의 범위 지정은 byte 단위가 아닌
한글은 1이란 숫자로 인식하기 때문에..
C 서버에서 이름 부분을 "홍길동1234" 이렇게
10자리로 채워서 보내줘도
JAVA 클라이언트는 substring(13, 10)을 통해
홍길동1234011 이런식으로 전화번호 (011) 부분
까지 읽어와 버립니다.
이럴때 바이트 단위로 매겨진 이름 10자리를
java에서도 온전히 읽을려면 어떻 방법이 있나요?
으~~~~~.. 질문이 제대로 올라 갔나 모르겠습니다
그럼 안녕히..
아.. 제가 위 문제를 해결하기 위해 허접 삽질한 코드도
올리겠습니다.
도움 부탁드립니다. 꾸벅..
import java.io.*; public class Test { public static void main(String[] args) throws IOException { String str = "안녕하세요"; System.out.println(str.length()); System.out.println(str+" length:"+str.length()); String newstr = new String(str.getBytes(), "ascii"); System.out.println(newstr+" length:"+newstr.length()); String substr = newstr.substring(0,4); // <<--- "안녕" 이란 두글자만 // substring 으로 읽을려고 시도 // 위에서 ascii로 변환 했기 때문에 // 0~4 하면 한글 2글자를 잘를거라 // 생각 했지만 결과는 한글이 깨져서 보임. ㅠㅠ; // println 에서 acsii로 conversion 된 문자를 찍기 위해 다시 유니코드로 변환.. String convstr = new String(substr.getBytes(), "8859_1"); //String convstr = new String(substr.getBytes(), "euc_kr"); //String convstr = new String(substr.getBytes(), "KSC5601"); System.out.println("**"+convstr); } }
우선 인코딩을 통일하셔야 합니다.
처음에 바이트 배열로 문자열을 만들때 C서버가 사용하는 인코딩과 java 클라이언트가 사용하는 인코딩을 같은 것으로 맞춰주세요. 그러면 주민번호와 이름을 잘라내는 코드가 문제 없이 돌아갈 듯 한데요. 예를 들어 서버측의 인코딩이 UTF-8 이면 new String(buffer, "UTF-8") 이 되겠죠.
[quote]예를 들어 서버측의 인코딩이 UTF-8 이면 new St
음.. 서버는 C로 되어있고 C는 특별히 한글이라고
인코딩 하지 않는 걸로 알고 있습니다. 단순히 바이트
로 처리를 하는 걸로.. 맞나?? 그러나 자바같은 경우
모든 한글은 어떤 인코딩 방식으로 된걸 String 객체가
제대로 인식 할수 있는거 같습니다..... 그렇다면
무엇으로 변경해야 옳은지..
String convstr = new String(substr.getBytes(), "8859_1");
String convstr = new String(substr.getBytes(), "euc_kr");
String convstr = new String(substr.getBytes(), "KSC5601");
이렇게는 해봤지만 한글 자체가 깨지는 문제가
있어 보입니다. 해결방법이 없을런지..
“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”
^^
C 프로그램에서도 당연히 문자 인코딩을 사용합니다. 인코딩은 프로그래밍 언어와는 관계 없습니다. 서버가 어떤 인코딩을 사용하는지는 서버 구현에 따라 다릅니다. 서버를 직접 구현하신게 아니라면 구현자에게 물어보시거나 서버의 문서를 살펴보시면 될겁니다. 그도 안된다면 일단 서버의 OS 를 살펴보세요. 만약에 리눅스라면 $LANG 변수의 값을 살펴보세요. 서버 OS의 기본 인코딩을 알아내실 수 있습니다. 하지만 서버 프로그램이 기본 인코딩을 사용하지 않고 자기 나름의 인코딩을 사용한다면 그 때는 정말 만든 사람에게 물어보거나 서버 문서 또는 설정 파일에서 알아내는 수 밖에 없습니다. 때로 서버가 아무런 인코딩도 사용하지 않을 수도 있습니다. 서버에 저장되어 있는 주민번호나 이름등을 클라이언트에서 데이터를 보내서 입력하는 거라면 인코딩을 변환하지 않고 그저 그 바이트를 그대로 저장했을 수도 있습니다. 그런 경우라면 클라이언트의 인코딩을 그대로 써주시면 되겠지요.
그리고 이런 코드를 쓰셨는데
제 말씀은 이런 뜻이 아니었습니다.^^;
예를 들어 서버로 부터 받은 로우 데이터가 byte[] data 에 들어있다면
이런 식으로 해보시라는 말씀이었습니다.
서버는 한글에 대해 따로 인코딩 하지 않습니다.그럼 해당 OS의
서버는 한글에 대해 따로 인코딩 하지 않습니다.
그럼 해당 OS의 인코딩을 따른 다는 말인데.
해당 리눅스는 LANG=ko_KR.eucKR 입니다.
따라서.
String rawString = new String(data, "euc_kr");
로 변환 후...
이름부분만 한다면.
String name = rawString.substring(13, 10);
마찬가지로 한글을 1로 생각하기 때문에 원하는 결과를
얻을 수 없었습니다.
정녕 간단한 인코딩은 안된단 말인가요?
구분자등을 입력해야 한단 ..말인가요.. ㅠㅠ
“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”
원하시는 답이 될런지는 모르겠습니다만,byte 개수로 자르신 뒤에
원하시는 답이 될런지는 모르겠습니다만,
byte 개수로 자르신 뒤에,
자른 byte array를 String으로 변환하시는게 편하지 않을까요?
질문에 보면, byte 수 기준으로 보내는 것 같은데,
byte array를 자르는 것으로 충분할법하여 말씀드립니다.
내용 추가합니다.
좀전에는 코드를 눈여겨 보지 않았었는데, 올리신 코드에 이런 부분이 보이는 군요
이렇게 쓰시면 str의 byte code를 ascii로 변환하는 것이 아니라,
str의 byte를 ascii로 간주하고 String을 생성합니다.
한데, str.getbytes()로 하면 JVM 디폴트로된 charset 만 반환합니다.
그렇기 때문에 newstr에는 깨진 한글이 들어가겠네요.
위의 String 생성자는
new String(xxxx charset byte array, Name of xxxx charset)
로 사용하실 때 쓰시면 좋습니다.
May The Force Be With You.
정확한 답은 아니지만..예전에 사용한 방법인데길이의 문제라면..
정확한 답은 아니지만..
예전에 사용한 방법인데
길이의 문제라면..
중간 중간에 특정한 특수 문자를 넣고..
그 특수 문자로 하여 각각의 변수에 담으면 될것 같습니다.
그렇게 하면 굳이 길이의 문제를 해결 하실수 있을것 같습니다.
이름이 2자 이거나 4자일때도 생각 하신다면 특수 문자로 처리하시는 것도 괜찮다고 생각합니다.
그럼 즐삽 하세요..^^
[quote]이렇게 쓰시면 str의 byte code를 ascii로
여기서 간주한다는 말의 의미를 잘 모르겠습니다.
간주 한단 말은 실제로는 JVM이 정한 charset만을
쓰지만 해당 String 객체는 인코딩 방식이 ascii인 것
이다...... 그렇다면... 모든 연산은 JVM 의 charset을
사용하니 실제적으로 위의 간주하는 방식은 쓸모가
없어 보입니다. 제가 식견이 짧아서 - - ;;;
그럼 위의 간주하는 방법이 어떻때 유용하게 쓰이나요?
감싸함다.
“바람에게도 길은 있다. 나는 비로소 나의 길을 가느니. 길은 언제나 어디에나 있다.”
댓글 달기