글쓴이 :김덕태 1998년 1월 20일 20:36:56
In Reply to: 한글 코드값 문제... posted by 김필호 on 1998년 1월 20일 18:03:27:
1. toHexString의 문제.
toHexString은 0으로 padding해주는 기능이 없고,
표준 API에 그런 기능이 없으며, 제대로 출력하려면
원시 화일의 간결성을 해치기 때문이었지만
프로그램을 수정하여 첨부하였습니다.
2. 한글을 8859-1 인코딩으로 변환할 때, 0x3F 코드값으로 변환하는 이유.
0x3F는 아스키 코드값으로 아스키 문자 '?'를 나타냅니다.
8859-1 인코딩으로 한글을 변환할 때, '?' 문자로 변환되는 이유는,
8859-1 인코딩에서는 한글 문자를 표현할 수 있는 코드값이 없어서
부득이 코드 변환 클래스가 '?'로 변환한 것입니다.
따라서, 코드 변환을 잘못하면 정보가 손실되는 위험이 있다는 것을
알 수 있습니다.
3. bytes[i] & 0xff 라고 한 이유.
자바에서는 byte 자료형이 무조건 signed 자료형입니다.
따라서, 코드값 128을 넘어가는 것은 모두 음수로 처리됩니다.
즉, toHexString 메쏘드의 인자의 자료형은 int인데,
바이트 자료형을 넘겨주면, 형변환이 발생하여 내부적으로
부호 확장을 한 int값으로 전달됩니다.
이와 같이 전달된 int값을 toHexString()으로 출력하면 아주
커다란 수로 나오게 됩니다.
그래서, 확장된 부호값을 잘라내기 위하여, 0xFF랑
& 연산을 한 결과를 넘겨준 것입니다.
import java.io.*;
class StringBytesConvTest
{ public static void main(String[] args)
throws IOException
{ byte[] buf = new byte[10000];
int count = 0;
for(int b; (b = System.in.read()) != -1; count++)
buf[count] = (byte) b;
byte[] ksc = new byte[count];
System.arraycopy(buf, 0, ksc, 0, count);
System.out.println( "KSC5601 (EUC-KR) 코드값 (16진수): "
+ toHex(ksc) );
String unicodes = new String(ksc, "KSC5601");
System.out.println( "유니코드 2.0 코드값 (16진수): "
+ toHex(unicodes) );
System.out.println( "역변환된 KSC5601 (EUC-KR) 코드값 (16진수): "
+ toHex(unicodes.getBytes("KSC5601")) );
System.out.println( "역변환된 8859_1 코드값 (16진수): "
+ toHex(unicodes.getBytes("8859_1")) );
System.out.println( "역변환된 UTF8 코드값 (16진수): "
+ toHex(unicodes.getBytes("UTF8")) );
System.out.write( ksc, 0, count );
System.out.print( unicodes );
System.out.flush();
}
static String toHex( byte[] codes )
{
String hex = pad0( Integer.toHexString(codes[0] & 0xff), 2 );
for( int i = 1; i < codes.length; i++ )
hex += " " + pad0( Integer.toHexString(codes[i] & 0xff), 2 );
return hex;
}
static String toHex( String unicodes )
{
String hex = pad0( Integer.toHexString(unicodes.charAt(0)), 4 );
for( int i = 1; i < unicodes.length(); i++ )
hex += " " + pad0( Integer.toHexString(unicodes.charAt(i)), 4 );
return hex;
}
static String pad0( String str, int size )
{ char[] zeros = new char[size - str.length()];
for( int i = 0; i < zeros.length; i++ )
zeros[i] = '0';
return new String( zeros ) + str;
}
}
C:\example\i18n> java StringBytesConvTest
ab가나 (리턴키를 친후, Control-Z 입력)
KSC5601 (EUC-KR) 코드값 (16진수): 61 62 b0 a1 b3 aa 0d 0a
유니코드 2.0 코드값 (16진수): 0061 0062 ac00 b098 000d 000a
역변환된 KSC5601 (EUC-KR) 코드값 (16진수): 61 62 b0 a1 b3 aa 0d 0a
역변환된 8859_1 코드값 (16진수): 61 62 3f 3f 0d 0a
역변환된 UTF8 코드값 (16진수): 61 62 ea b0 80 eb 82 98 0d 0a
ab가나
ab가나