ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • String to hex을 hex byte array
    개발/JAVA 2019. 3. 22. 11:12

     소켓통신은 byte형태로 송신하고 수신한다. 따라서 보낼 데이터는 바이트 형태로 인코딩을 하게된다.

     1 byte = 8 bit,

     1 bit 는 0,1 2진수 인 것을 모두 잘 알 것이다.

     따라서 1 byte는 8bit 이므로 2^8으로 이루어져 있고 10진수로는 0~255, 

     16진수로는 0~ff까지의 값을 가진다.

     흔히 문자를 바이트로 16진수의 2자리 값으로 나타내며 Apple을 예를들면


       String str = "Apple";


        // 한 글자씩 헥사(Hex)로 출력

        System.out.println(stringToHex(str));

        // 출력 결과: 41 70 70 6C 65


        // 접두사 붙여서 출력

        System.out.println(stringToHex0x(str));

        // 출력 결과: 0x41 0x70 0x70 0x6C 0x65


    이러한 형태가 된다. 


     아무튼 이러한 형태로 데이터를 전송하고 받는 간단한 서버를 구축하는 작업을 하고 있는 중 문자를 unicode 형태의 byte 배열로 바꾸라는 얘기를 들었다. 

    갑자기 유니코드라니? 문자를 유니코드로 변환하는 것은 알고 있었지만 여기서 또 바이트라니? 여기서 멘붕으로 인한 삽질이 시작되었다.

     String -> unicode 

     unicode -> byte[] 는 

    1문자 -> 4자리의 유니코드 -> 4자리의 유니코드 -> 유니코드를 스트링으로 인식 -> 바이트


    문자를 바이트로 변환하는 것은 


    byte[] bytes = str.getBytes();


    문자를 헥사값으로 바꾸는 것은



     public static String escape(String src) {   

      

            int i;   

            char j;   

            

            char[] CharSrc=src.toCharArray();

            

            StringBuffer tmp = new StringBuffer();   

            tmp.ensureCapacity(src.length() * 6);  

            ByteBuffer buffer =  ByteBuffer.allocate(1024);  

            byte[] body = new byte[CharSrc.length*2];       

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

           

            tmp.append(String.format("\\u%04x ", (int) CharSrc[i]));

           

            }   

            return tmp.toString();   

    }   


    메소드를 통해 작업하면 된다.



    이게 과연 필요한가 의문이 들었고 몇번의 확인 끝에

    1문자->1글자의 hex byte가 아닌 1문자 -> 뒤에 00을 가진 2byte 로 표현해달라는 얘기였다.(이것 또한 무슨소리인가 이해가 안 갈 수도 있다)



    다시 문자를 헥사 바이트로 변환하는 작업은


    문자를 헥사형태의 스트링으로변환 후 바이트에

    담는 방법을 사용했다.


      public static String stringToHex(String s) {

        String result = "";


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

          result += String.format("%02x ", (int) s.charAt(i));

        }


        return result;

      }




    public static byte[] hexStringToByteArray(String hexString) {

       

    String[] hexString_split = hexString.split(" ");

    byte[] hexBytes= new byte[hexString_split.length];

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

    hexBytes[i]= (byte)Integer.parseInt(hexString_split[i], 16);

    }


        return hexBytes;

    }



    그리고



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

    System.out.print(bytes[i]);

    }


    와 같이 확인을 하면서 삽질이 또 시작되었다.

    16진수로 분명 담았는데 출력은 10진수의 값으로 반복해서 나오는 것이었다.

    헥사저장이 잘못된 줄 알고 변환하는 여러방법을 써 봤지만 마찬가지였다.

    그리고 byte에 저장된 값을 출력할때 포맷을 설정하지 않아

    동일한 값이 print()의 기본설정값인(추측이지만) 10진수로 출력 된 것이다.

    따라서 

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

    System.out.printf("%02x ", hexBytes[i]);

    }


    로 하면 기존의 헥사형태로 출력되고,

    데이터 역시 정상적으로 문자 -> byte형태가 된 걸로 파악할 수 있다.

    여기서 생기는 의문은 string -> getbyte를 통해 byte[] 에 담긴 형태와

    이러한 작업을 거친 것의 차이가 있는것인지다.


    확인해 봐야할 문제다.


    댓글

Designed by Tistory.