> Java > java지도 시간 > Java 인코딩 변환 프로세스는 무엇입니까?

Java 인코딩 변환 프로세스는 무엇입니까?

PHPz
풀어 주다: 2023-04-19 13:10:06
앞으로
1736명이 탐색했습니다.

    Java에서 인코딩 변환(utf8 및 gbk를 예로 사용)

    일반적인 Java 웹 개발에서는 한자가 깨져서 문자로 변환되는 현상이 종종 발생합니다. 지금까지 헷갈려서 테스트 코드를 작성해 보았는데 드디어 인코딩을 명확하게 정리하고 먼저 결론을 내렸습니다.

    utf8은 다양한 언어 인코딩을 저장합니다. 현재 utf8은 주류 개발에서 인코딩 및 디코딩에 사용됩니다. 다음 상황에서는 잘못된 코드가 발생합니다: 1, gbk(중국어), iso-8859-1(중국어 없음) 및 기타 인코딩 그렇지 않으면 문자가 깨집니다

    • 2. 다른 방법으로 인코딩 및 디코딩에 utf8을 사용하면 문자가 깨져서 변환이 필요합니다

    • 3. 해당 문자(중국어)가 없는 문자 집합(iso-8859-1)을 사용하면 코드가 깨져서 디코딩을 복원할 수 없습니다

    • 다음은 위 상황에 대한 코드 테스트입니다

    • 1. decode
    /**
     * 测试编码转换 中文 => utf-8 编码 - 解码
     */
    @Test
    public void test0() {
        String test = "测试";
        System.out.println(Arrays.toString(test.getBytes(StandardCharsets.UTF_8)));//[-26, -75, -117, -24, -81, -107]
        System.out.println(new String(test.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));//测试
    }
    로그인 후 복사
    /**
     * 测试编码转换 中文 => gbk 编码 - 解码
     */
    @Test
    public void test1() throws UnsupportedEncodingException {
        String test = "测试";
        System.out.println(Arrays.toString(test.getBytes("gbk")));//[-78, -30, -54, -44]
        System.out.println(new String(test.getBytes("gbk"), "GBK"));//测试
    }
    로그인 후 복사

    utf8 인코딩-잘못된 형식 Decode

    /**
     * 测试编码转换 中文 => utf-8 编码- gbk解码
     */
    @Test
    public void test2() throws UnsupportedEncodingException {
        String test = "测试";
        System.out.println(Arrays.toString(test.getBytes(StandardCharsets.UTF_8)));//[-26, -75, -117, -24, -81, -107]
        System.out.println(new String(test.getBytes(StandardCharsets.UTF_8), "gbk"));//娴嬭瘯
    }
    로그인 후 복사

    올바른 방법은 잘못된 디코딩 형식(gbk)을 전송으로 누르고, 잘못된 형식(gbk)에 따라 다시 인코딩(utf8-encode)한 다음, utf8을 사용하여 올바른 디코딩(utf8-decode)을 수행하여 원본 문자를 가져옵니다

    /**
     * 测试编码转换 中文 => utf-8 编码 - gbk 解码 ===> gbk 编码 - utf-8解码
     * "测试" => (utf8-encode)[-26, -75, -117, -24, -81, -107] => (gbk-decode)娴嬭瘯
     * "娴嬭瘯" => (utf8-encode)[-26, -75, -117, -24, -81, -107] => (utf8-decode)"测试"
     */
    @Test
    public void test3() throws UnsupportedEncodingException {
        String test = "测试";
        String test_gbk_utf8 = new String(test.getBytes(StandardCharsets.UTF_8), "gbk");
        System.out.println(test_gbk_utf8);//娴嬭瘯
        String test_utf8_gbk = new String(test_gbk_utf8.getBytes("gbk"), StandardCharsets.UTF_8);
        System.out.println(test_utf8_gbk);//测试
    
    }
    로그인 후 복사

    3. 해당 문자 인코딩이 없습니다

    @Test
        public void test4() throws UnsupportedEncodingException {
            String test = "测试";
            System.out.println(Arrays.toString(test.getBytes(StandardCharsets.ISO_8859_1)));//[63, 63]
            System.out.println(new String(test.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.ISO_8859_1));//??
        }
    로그인 후 복사

    이 경우 원래 인코딩 방법을 사용하여 디코딩하더라도 문자를 복원할 수 없습니다.

    Java 인코딩 형식 변환 및 잘못된 코드 복구

    Java에서 인코딩 형식 변환을 수행하는 방법

    다음 코드 줄의 의미는 다음과 같습니다. 대상 문자열 str의 바이너리 코드를 가져옵니다. gbk 인코딩 형식으로 변환한 후 utf8 인코딩 형식에 따라 바이너리 코드를 문자열로 다시 인코딩합니다. 물론 다음 작성 방법은 인코딩 형식이 일치하지 않기 때문에 100% 왜곡됩니다.

    new String(str.getBytes("gbk"),"utf8")
    로그인 후 복사

    우선 어떤 상황에서는요. 코드가 깨질까요? 문자열을 전송하려면 먼저 특정 인코딩 형식에 따라 문자열을 바이트 스트림으로 변환해야 합니다. 바이트 스트림이 수신자에게 전송되면 바이트 스트림을 특정 인코딩 형식으로 변환해야 합니다. 문자열로 다시 변환하는 과정에서 왜곡된 문자도 생성됩니다. 다음은 중국어 왜곡된 문자에 대한 테스트입니다.

      String str="彩虹";
            String [] a=new String[] {"gbk","unicode","utf8","gb2312"};
            for (int i=0;i<a.length;i++){
                for (int j=0;j<a.length;j++){
                    System.out.println("二进制格式:   "+a[i]+"编码格式:  "+a[j]);
                    System.out.println("编码后的字符串:  "+new String(str.getBytes(a[i]),a[j]));
     
                }
            }
    로그인 후 복사

    바이너리 형식: gbk 인코딩 형식: gbk

    인코딩된 문자열: Rainbow

    바이너리 형식: gbk 인코딩 형식: unicode

    인코딩 문자열: 닊뫧

    바이너리 형식: gbk 인코딩 형식: utf8
    인코딩 문자열: �ʺ�

    바이너리 형식: gbk 인코딩 형식: gb2312
    인코딩 문자열: Rainbow
    바이너리 형식: 유니코드 인코딩 형식: gbk
    인코딩된 문자열: �_i唝
    바이너리 형식: 유니코드 인코딩 형식: unicode
    인코딩 문자열: Rainbow
    바이너리 형식: 유니코드 인코딩 형식: utf8
    인코딩 문자열: ��_i�y
    바이너리 형식: 유니코드 인코딩 형식: gb2312
    인코딩된 문자열: ��_i�y
    바이너리 형식: utf8 인코딩 형식: gbk
    인코딩된 문자열: 褰╄櫣
    바이너리 형식: utf8 인코딩 형식: unicode
    인코딩된 문자열: ꧨ馹
    바이너리 형식: utf8 인코딩 형식: utf8
    인코딩된 문자열: Rainbow
    바이너리 형식: utf8 인코딩 형식: gb2312
    인코딩된 문자열:褰╄��
    바이너리 형식: gb2312 인코딩 형식: gbk
    인코딩된 문자열: Rainbow
    바이너리 형식: gb2312 인코딩 형식: unicode
    인코딩된 문자열: 닊뫧
    바이너리 형식: gb2312 인코딩 형식: utf8
    encoded 문자열: �ʺ�
    바이너리 형식: gb2312 인코딩 형식: gb2312
    인코딩 문자열: Rainbow


    바이너리 인코딩 형식과 의 인코딩 형식이 다른 경우라고 볼 수 있습니다. 문자열이 다르면 잘못된 문자가 발생합니다.

    gbk, gb2312 변환에 잘못된 코드가 없는 이유는 무엇입니까?

    gbk는 gb2312의 향상된 버전이고 더 많은 한자를 지원하기 때문에 gbk와 gb2312 간의 변환에 잘못된 코드가 없습니다. 인코딩이므로 바이너리 인코딩 형식이 gbk이고 디코딩 형식이 gb2312인 경우 이러한 상황은 일부 한자가 깨졌을 가능성이 있습니다. 깨진 데이터를 다시 변환할 수 있습니까? 위 결과에서 깨진 문자는 대략 두 가지로 나눌 수 있습니까? 하나는 한자와 그래픽의 복잡한 조합이고, 다른 하나는 "?"입니다.

    복구하려는 왜곡된 데이터에 물음표가 있으면 이 데이터를 제외하면 복구 가능성이 낮기 때문입니다. "?"의 경우 다른 왜곡된 문자에는 실제로 자체 인코딩 규칙이 있습니다. 이를 역디코딩하고 준수하는 한 올바른 인코딩 형식으로 다시 코딩하면 복원할 수 있습니다. 그러나 "?"는 예외입니다. 특정 인코딩 형식에 따라 인코딩 형식에 따라 의미 있는 문자로 변환할 수 없는 바이트 데이터의 바이트는 "?"로 변환되므로 바이트 스트림으로 역방향으로 인코딩되더라도 모두 "?" 동일한 바이트로 변환되므로 그 자체의 의미를 잃게 됩니다.

    如果乱码中不包含"?",那么还是有希望转换回去的,我以上述乱码中的 "褰╄櫣" 为例重新进行了一次转换,代码如下:

           String str="褰╄櫣";
            String [] charset=new String[] {"gbk","unicode","utf8","gb2312"};
            for (int i=0;i<charset.length;i++){
                for (int j=0;j<charset.length;j++){
                    System.out.println("二进制格式:   "+charset[i]+"编码格式:  "+charset[j]);
                    System.out.println("编码后的字符串:  "+new String(str.getBytes(charset[i]),charset[j]));
     
                }
            }
    로그인 후 복사

    二进制格式:   gbk编码格式:  gbk
    编码后的字符串:  褰╄櫣
    二进制格式:   gbk编码格式:  unicode
    编码后的字符串:  ꧨ馹
    二进制格式:   gbk编码格式:  utf8
    编码后的字符串:  彩虹
    二进制格式:   gbk编码格式:  gb2312
    编码后的字符串:  褰╄��
    二进制格式:   unicode编码格式:  gbk
    编码后的字符串:  ��0%Dj�
    二进制格式:   unicode编码格式:  unicode
    编码后的字符串:  褰╄櫣
    二进制格式:   unicode编码格式:  utf8
    编码后的字符串:  ���0%Dj�
    二进制格式:   unicode编码格式:  gb2312
    编码后的字符串:  ���0%Dj�
    二进制格式:   utf8编码格式:  gbk
    编码后的字符串:  瑜扳晞娅�
    二进制格式:   utf8编码格式:  unicode
    编码后的字符串:  냢閄�
    二进制格式:   utf8编码格式:  utf8
    编码后的字符串:  褰╄櫣
    二进制格式:   utf8编码格式:  gb2312
    编码后的字符串:  瑜扳��娅�
    二进制格式:   gb2312编码格式:  gbk
    编码后的字符串:  褰╄?
    二进制格式:   gb2312编码格式:  unicode
    编码后的字符串:  ꧨ�
    二进制格式:   gb2312编码格式:  utf8
    编码后的字符串:  彩�?
    二进制格式:   gb2312编码格式:  gb2312
    编码后的字符串:  褰╄?

    可以看到 其中一种转换方式成功的将乱码转变回了正常的中文汉字

    二进制格式:   gbk编码格式:  utf8
    编码后的字符串:  彩虹

    위 내용은 Java 인코딩 변환 프로세스는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    관련 라벨:
    원천:yisu.com
    본 웹사이트의 성명
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
    인기 튜토리얼
    더>
    최신 다운로드
    더>
    웹 효과
    웹사이트 소스 코드
    웹사이트 자료
    프론트엔드 템플릿