Total: Today: Yesterday:
개발/JAVA | 2015. 3. 3. 15:58 | Posted by 자수씨

출처: http://codereview.stackexchange.com/questions/59428/validating-utf-8-byte-array


charset 이 불확실한 상황에서 여러 시스템에서 xml 기반 데이터를 주고 받다보면 charset 으로 인해 문베가 발생하곤한다.


A라는 시스템에서는 xml 은 utf-8 기반인데, 안에 있는 내용(BASE64 로 인코딩한)은 euc-kr 방식이고, B라는 시스템에서는 xml 은 utf-8 기반이고, 안에 있는 내용도 utf-8 방식이다.


위의 상황이라면 A와 B를 둘 다 만족시킬 수 있는 시스템을 만들기 위해서는 byte array 가 utf-8 인지 euc-kr 인지 구분이 필요하다.

(utf-8로 디코딩해야 하는 상황이라면 아래의 검사 후 utf-8이 아니라면 euc-kr 로 다시 디코딩)


참고했던 페이지는 Java 7 기반으로 되어 있어서 Java 6 기반으로 바꾸어보았다.


in Java 6

###java

public class ValidateUtf8 {


    /**

     * Returns the number of UTF-8 characters, or -1 if the array does not

     * contain a valid UTF-8 string. Overlong encodings, null characters,

     * invalid Unicode values, and surrogates are accepted.

     *

     * @param bytes byte array to check length

     * @return length

     */

    public static int charLength(byte[] bytes) {

        int charCount = 0, expectedLen;


        for (int i = 0; i < bytes.length; i++) {

            charCount++;

            // Lead byte analysis

            if ((bytes[i] & Integer.parseInt("10000000", 2)) == Integer.parseInt("00000000", 2)) {

                continue;

            } else if ((bytes[i] & Integer.parseInt("11100000", 2)) == Integer.parseInt("11000000", 2)) {

                expectedLen = 2;

            } else if ((bytes[i] & Integer.parseInt("11110000", 2)) == Integer.parseInt("11100000", 2)) {

                expectedLen = 3;

            } else if ((bytes[i] & Integer.parseInt("11111000", 2)) == Integer.parseInt("11110000", 2)) {

                expectedLen = 4;

            } else if ((bytes[i] & Integer.parseInt("11111100", 2)) == Integer.parseInt("11111000", 2)) {

                expectedLen = 5;

            } else if ((bytes[i] & Integer.parseInt("11111110", 2)) == Integer.parseInt("11111100", 2)) {

                expectedLen = 6;

            } else {

                return -1;

            }


            // Count trailing bytes

            while (--expectedLen > 0) {

                if (++i >= bytes.length) {

                    return -1;

                }

                if ((bytes[i] & Integer.parseInt("11000000", 2)) != Integer.parseInt("10000000", 2)) {

                    return -1;

                }

            }

        }

        return charCount;

    }


    /**

     * Validate a UTF-8 byte array

     *

     * @param bytes byte array to validate

     * @return true if UTF-8

     */

    public static boolean validate(byte[] bytes) {

        return (charLength(bytes) != -1);

    }

}



in Java 7 이상

### java

public class ValidateUtf8 {


    /**

     * Returns the number of UTF-8 characters, or -1 if the array does not

     * contain a valid UTF-8 string. Overlong encodings, null characters,

     * invalid Unicode values, and surrogates are accepted.

     *

     * @param bytes byte array to check length

     * @return length

     */

    public static int charLength(byte[] bytes) {

        int charCount = 0, expectedLen;


        for (int i = 0; i < bytes.length; i++) {

            charCount++;

            // Lead byte analysis

            if ((bytes[i] & 0b10000000) == 0b00000000) {

                continue;

            } else if ((bytes[i] & 0b11100000) == 0b11000000) {

                expectedLen = 2;

            } else if ((bytes[i] & 0b11110000) == 0b11100000) {

                expectedLen = 3;

            } else if ((bytes[i] & 0b11111000) == 0b11110000) {

                expectedLen = 4;

            } else if ((bytes[i] & 0b11111100) == 0b11111000) {

                expectedLen = 5;

            } else if ((bytes[i] & 0b11111110) == 0b11111100) {

                expectedLen = 6;

            } else {

                return -1;

            }

            // Count trailing bytes

            while (--expectedLen > 0) {

                if (++i >= bytes.length) {

                    return -1;

                }

                if ((bytes[i] & 0b11000000) != 0b10000000) {

                    return -1;

                }

            }

        }

        return charCount;

    }


    /**

     * Validate a UTF-8 byte array

     *

     * @param bytes byte array to validate

     * @return true if UTF-8

     */

    public static boolean validate(byte[] bytes) {

        return (charLength(bytes) != -1);

    }

}


개발/JAVA | 2015. 2. 11. 18:03 | Posted by 알 수 없는 사용자

담당하고 있는 모듈의 프로젝트가 여러개일때 버전 관리 문제로 자수씨의 도움으로 메이븐방식으로 프로젝트 구조를 잡게 되었다.

프로젝트 안에 프로젝트들이 있다고 생각하면 쉽다.

관리도 프로젝트 하듯이 관리하면 된다.


구조 만들기

1. 메이븐 프로젝트를 생성한다.

 

또는   에서 Maven Project 검색

2. 딱히 설정할 것 없으면 next

* 꼭 위에 선택한대로 선택 안해도 된다


3. Group Id, Artifact Id 필수 입력 입니다. 입력하고 Finish


6. 프로젝트를 생성하면 아래와 같이 구조가 잡힌다.



위의 pom.xml을 열어 수정한다.  >>     -> 



7. 부모 부로젝트는 소스 부분이 필요 없으니 실제 프로젝트가 작업 공간으로 이동해서 네모 친 부분 삭제.

* 소스가 필요 없다면 굳이 .settings 폴더에 org.eclipse.jdt.core.prefs가 필요없다.


8. 삭제하고 난 뒤 이클립스에서 보여지는 프로젝트


9. 본격적으로 자식 프로젝트들을 추가한다. 

또는   에서 Maven Module 검색


10. 네모친 부분 입력하고 working set 경로 확인하고 next 후 finish

* 아래 네모는 자동으로 입력된다. finish


그럼 이제 프로젝트 안에 모듈이 포함되었다.

* 이클립에서 모듈이 추가되었을때 보여지는 화면

간단하게 설명하자면 

test-module (부모프로젝트) test-module-ui 라는 모듈을 포함시키면서 test-module-ui 프로젝트 가 만들어지면서 포함되는 형식.

따라서 test-module-ui 프로젝트와 test-module프로젝트의 test-module-ui 모듈은 같은거다.


9 - 10 단계를 거쳐 또 다른 모듈을 추가 시킨다면 아래와 같이 두개 생성 된다.



test. 프로젝트에서 수정하였 을 때 모듈에서 적용 될까?


test-1. App.java

 


test-2. 이름 바꿈.


test-1. 이름이 바뀜.


* 참고 *

부록 - 부모 폼 정보 / test-module.pom.xml


부록 - 자식 폼 정보 / test-module-ui.pom.xml

부록 - 자식 폼 정보 / test-module-server.pom.xml


버전 관리 방법

부모 폼에서 버전을 수정하면 자식 모듈의 버전 정보를 수정하면 끝이다.


<추가>

위 구조로 되어있는 프로젝트가 SVN으로 올라 왔을 경우 체크아웃 받을때 자동으로 프로젝트를 잡지 못한다.

이럴 경우 import > Maven > Existing Maven Projnect 를 선택하는 것을 참조한다.