복붙노트

[SCALA] -127와 다시 문자열을 바이트 배열에 .. 문제

SCALA

-127와 다시 문자열을 바이트 배열에 .. 문제

다음의 경우 :

 scala> (new String(Array[Byte](1, 2, 3, -1, -2, -127))).getBytes
 res12: Array[Byte] = Array(1, 2, 3, -1, -2, 63)

왜 -127 (63)로 변환된다? 그리고 어떻게 -127로 다시받을 수 있나요

[편집 :] 아래의 Java 버전 (쇼에 자사 다만 "스칼라 문제")

c:\tmp>type Main.java
public class Main {
    public static void main(String [] args) {
        byte [] b = {1, 2, 3, -1, -2, -127};
        byte [] c = new String(b).getBytes();
        for (int i = 0; i < 6; i++){
            System.out.println("b:"+b[i]+"; c:"+c[i]);
        }
    }
}
c:\tmp>javac Main.java
c:\tmp>java Main
b:1; c:1
b:2; c:2
b:3; c:3
b:-1; c:-1
b:-2; c:-2
b:-127; c:63

해결법

  1. ==============================

    1.문자열 (바이트 [] 바이트 캐릭터 세트의 캐릭터 세트) : 생성자 당신이있는 거 호출 바이너리를 문자열로 변환이 디코딩을 사용하는 것이 아닌 분명합니다. 당신이 원하는 것은 전혀 디코딩에는 사용할 수 없습니다.

    문자열 (바이트 [] 바이트 캐릭터 세트의 캐릭터 세트) : 생성자 당신이있는 거 호출 바이너리를 문자열로 변환이 디코딩을 사용하는 것이 아닌 분명합니다. 당신이 원하는 것은 전혀 디코딩에는 사용할 수 없습니다.

    다행히도, 그의 생성자가있다 : 문자열 (문자 [] 값).

    지금 당신은 문자열의 데이터를 가지고 있지만, 정확히 그대로 다시합니다. 하지만 그거 알아! 의 바로 부호화가 있다는 getBytes (문자셋 문자셋)도 자동적으로 적용 하였다. 다행히 toCharArray () 방법이있다.

    당신이 바이트로 시작하고 바이트로 종료해야하는 경우에는 다음 바이트의 문자 배열을 매핑해야합니다 :

    (new String(Array[Byte](1,2,3,-1,-2,-127).map(_.toChar))).toCharArray.map(_.toByte)
    

    따라서, 요약 [바이트] 부호화 및 복호화 관련 문자열과 배열 간의 변환. 당신이 문자열에서 이진 데이터를 넣어하려는 경우, 당신은 문자의 수준에서 그것을 할 수 있습니다. 단,이 당신에게 쓰레기 문자열을 줄 것이다 (즉, 결과가 잘 형성되지 않습니다 UTF-16 문자열이 될 것으로 예상 될 때)을 당신이 더 문자로 그것을 읽고 그것을 다시 변환 줄 수 있도록하고, 바이트.

    당신은, 말하자면,에 의해 바이트 512을 추가 이동할 수있다; 당신은 유효한 하나의 샤아 코드 포인트의 무리를 얻을 것입니다. 그러나 모든 8, 50 %의 부호화 효율을 나타내는 16 비트를 사용한다. 64 기수 (8 비트 6 75 %의 효율을 대표하는) 이진 데이터를 직렬화하기위한 더 나은 방법이다.

  2. ==============================

    2.문자열 이진 데이터를 텍스트를 저장하지 않는입니다.

    문자열 이진 데이터를 텍스트를 저장하지 않는입니다.

    기본 문자 인코딩에서는이로 대체 있도록 -127에 대한 문자가 없다 '?' 63.

    편집이 : Base64로 최선의 선택이다, 더 나은 이진 데이터를 저장하기 위해 텍스트를 사용하지 않도록 할 것이다. 그것은 아닌 표준 문자 인코딩, 수행 할 수 있습니다. 즉 당신은 자신을 인코딩해야한다.

    말 그대로 귀하의 질문에 대답하기 위해, 당신은 당신의 자신의 문자 인코딩을 사용할 수 있습니다. 텍스트 가능성이 인코딩 당신이 본대로 같은 방식으로 망가 얻는 것입니다 이것은 아주 나쁜 생각이다. Base64로를 사용하면 어떤 인코딩의 안전 문자를 사용하여이 문제를 피할 수 있습니다.

    byte[] bytes = new byte[256];
    for (int i = 0; i < bytes.length; i++)
        bytes[i] = (byte) i;
    String text = new String(bytes, 0);
    byte[] bytes2 = new byte[text.length()];
    for (int i = 0; i < bytes2.length; i++)
        bytes2[i] = (byte) text.charAt(i);
    int count = 0;
    for (int i = 0; i < bytes2.length; i++)
        if (bytes2[i] != (byte) i)
            System.out.println(i);
        else
            count++;
    System.out.println(count + " bytes matched.");
    
  3. ==============================

    3.StringOps 내가 그 일이 실제로 배열에 문자열을 변환 원하는 것을 아마 생각, 메소드 getBytes있다 [바이트]

    StringOps 내가 그 일이 실제로 배열에 문자열을 변환 원하는 것을 아마 생각, 메소드 getBytes있다 [바이트]

    http://www.scala-lang.org/api/2.10.2/index.html#scala.collection.immutable.StringOps

  4. ==============================

    4.올바른 문자 집합을 사용하여

    올바른 문자 집합을 사용하여

    scala> (new String(Array[Byte](1, 2, 3, -1, -2, -127), "utf-16")).getBytes("utf-16")
    res13: Array[Byte] = Array(-2, -1, 1, 2, 3, -1, -2, -127)
    
  5. from https://stackoverflow.com/questions/5250324/byte-array-to-string-and-back-issues-with-127 by cc-by-sa and MIT license