2012-03-16 2 views
5

이유가 있다는 사실이 아니다 :왜 아니다`Encoding.UTF8.GetBytes (Encoding.UTF8.GetString (X)) == .NET에서 x`

Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(x)) 

원래 바이트 배열을 반환 임의의 바이트 배열 x?

다른 질문에 대한 대답은 mentioned이지만 응답자는 이유를 설명하지 않습니다.

+0

UTF-8이 아닌 ASCII에 관한 회답에 링크 된 대답입니다. – svick

+1

'=='를 사용하여 바이트 배열을 비교할 수 있습니까? 아마 단지 참조를 비교하기 만하면 아마 배열의 각 요소를 비교하기 위해 루프를 만들어야 할 것입니다. – Matthew

+0

@Matthew [그 대답] (http://stackoverflow.com/a/3946274/85371)의 요지는 인코딩이 다를 수있는 것으로 보입니다. 그리고 예 코드는 결함이 있습니다/거꾸로. – sehe

답변

1

문자 인코딩 (UTF8, 구체적으로)은 동일한 코드 포인트에 대해 다른 형식을 가질 수 있습니다.

문자열로 변환 할 때 실제 바이트는 다른 (정식) 형식 일 수 있습니다.

일부 유니 코드 시퀀스는 단점은 다음과 같습니다

String.Normalize(NormalizationForm.System.Text.NormalizationForm.FormD)

페이지 참조 동일한 문자를 나타 내기 때문에 동일하다. 이 중 하나가 "A"를 나타내는 데 사용할 수 있기 때문에 예를 들어, 다음은 동일하게 간주됩니다

"\u1EAF" 
"\u0103\u0301" 
"\u0061\u0306\u0301" 

그러나, 서수, 이진, 비교가 서로 다른 유니 코드 값에 포함되어 있기 때문에 순서가 다른 고려된다. 순서 비교를 수행하기 전에 응용 프로그램은 이러한 문자열을 정규화하여 기본 구성 요소로 분해해야합니다.

그 페이지 인코딩 항상 == 배열의 각 요소를 비교하지 않기 때문이다

+0

두 가지 방법 중 하나라도 문자열의 형식을 변경하는 이유는 무엇입니까? – svick

+0

@svick 묻지 마십시오. 나는 그것이 일어나지 않을 것이라는 것을 확신하기 위해 문서를 확인하지 않았다. 그러나 – sehe

+0

나는 이것이 일어나지 않을 것이라고 생각한다. 이러한 형태는 다양한 인코딩의 속성이 아니라 유니 코드 자체의 특성이기 때문입니다. 따라서 한 문자는 다른 코드 포인트 순서로 표현 될 수 있습니다. 그러나 특정 코드화를 사용하면 코드 포인트의 단일 시퀀스를 바이트 시퀀스로 표시 할 수 있습니다. – svick

1

정규화 무엇인지를 보여주는 좋은 예제와 함께 제공됩니다. Encoding.UTF8과 관련이 없습니다. 확인이 : watbywbarif가 언급 한 바와 같이

var a = new byte[] { 1 }; 
var b = new byte[] { 1 }; 
bool res = a == b; 
3

첫째, 당신이 ==를 사용하여 시퀀스를 비교해서는 안, 그 작동하지 않습니다.

하지만 배열을 올바르게 비교하더라도 (예 : SequenceEquals()을 사용하거나이를보고 만) 항상 동일하지는 않습니다. 이러한 경우가 발생할 수있는 경우는 x이 잘못된 UTF-8 인코딩 된 문자열 인 경우입니다.

예를 들어 0xFF의 1 바이트 시퀀스는 유효한 UTF-8이 아닙니다. 그렇다면 Encoding.UTF8.GetString(new byte[] { 0xFF })은 무엇을 반환합니까? 그것은 , U + FFFD, REPLACEMENT CHARACTER입니다. 물론, Encoding.UTF8.GetBytes()으로 전화하면 다시 0xFF이 붙지 않습니다.

+0

+1, 좋은 예제 – sehe

+1

나는'SequenceEqual' 확장 메소드에 대해 몰랐다. 매우 유용했다. – PyreneesJim

1

에서이에서 오는 또 다른 각도는 Encoding 클래스 왕복 데이터 설계하지만 그들은 왕복을 설계하고 데이터가 byte 다른 방법은 주위에 인코딩, char 데이터 점이다 .이것이 의미하는 바는 해당 Encoding의 기능 내에서 각 char 값은 byte 값 (1 이상)에 해당하는 인코딩을 가지며 정확하게 동일한 값으로 되돌아갑니다. (그것은 모든 Encoding모든char 값이 할 수없는 것을 주목할 필요가있다 - 예를 들어, 의 범위 [0, 128)char 값 만 지원할 수 있습니다.)

그래서, 당신은 문자로 시작하는 경우 데이터를 저장하거나 바이트 (디스크 또는 네트워크 스트림의 파일과 같은)를 사용하는 매체에 저장하거나 전송하는 방법이 필요하면 char 데이터를 byte 데이터로 변환 한 다음 다시 다른 끝. (모든 문자열을 지원하려는 경우, 당신은 Encoding.Unicode 또는 Encoding.UTF8와 같은 유니 코드 기반 Encoding들 중 하나를 사용해야합니다.)

그래서, 이것은 당신이 시작하는 경우 무엇을 의미 하는가 byte s의 무리? 글쎄, 문제의 인코딩에 따라 이 출력 할 시퀀스가 ​​실제로 작업하는 것이 아닌 byte이 될 수 있습니다. 당신은 인코딩 작업으로 Encoding.GetBytes 볼 필요하고, 디코딩 동작으로 Encoding.GetChars/Encoding.GetString, 그래서 당신은 임의의 바이트 배열에서 시작하여 디코드을하려고하고 있습니다.

비유하자면 이미지의 경우 JPEG 파일 형식을 고려하십시오. 이것은 유사한 유형의 을 디코딩합니다.이 경우 디코딩 된 데이터는 string이 아니라 이미지입니다. 따라서 임의의 바이트 문자열을 가져 오는 경우 JPEG 이미지로 디코딩 될 수있는 기회는 무엇입니까? 분명히 그 대답은 매우 희박합니다. 더 많은 경우, 당신의 바이트는 디코더의 경로를 따라 가게 될 것입니다. "와우, 그 바이트가 다른 하나를 따라 올 것이라고 기대하지 않았습니다."그리고 가정에서 데이터를 처리하기 위해 최선을 다할 것입니다 그것은 그것이 어떻게 든 손상된 유효한 JPEG 파일이라는 것입니다.

임의의 바이트 배열을 문자열로 변환하면 똑같은 일이 발생합니다. UTF-8 인코딩에는 char 값이 128 이상으로 인코딩되는 방식에 대한 특정 규칙이 있으며 그 중 하나는 110xxxxx, 1110xxxx 또는 11110xxx과 같은 패턴과 일치하는 비트 패턴 10xxxxxx 다음에 일치하는 바이트를 볼 수 있다고 말합니다. 멀티 바이트 시퀀스 ("char"을 나타내는 다중 byte)를 "도입"합니다. 따라서 데이터에 10xxxxxx 패턴과 일치하는 바이트가 포함 된 경우 이 예상되는 "소개자"중 하나를 따르지 않으므로 인코더는 데이터가 어떻게 든 손상되었다고 추측 할 수 있습니다. 그것은 무엇을합니까? 그것은 "인코딩 된 데이터에 끔찍한 잘못이 생겼습니다. 최선을 다했습니다. 이것이 잘못 된 부분입니다." 유니 코드를 설계 한 사람들은이 정확한 시나리오를 예상하고 정확한 의미의 문자를 만들었습니다 : Replacement Character. 당신이하려는 경우

그래서, char s의 문자열에 byte들 왕복이 시나리오는 잘못된 byte의 실제 값은 분실, 대신에 대체 문자가 삽입되어 발생합니다. stringbyte 배열로 되돌리려면 원래 데이터가 아닌 대체 문자 인코딩이 끝납니다. 원래 데이터가 손실됩니다.

당신이 찾고있는 것은 인코딩 방향이 다른 방향으로 동작하는 & 디코딩입니다. Encodingchar 데이터를 가져 와서 임시로 데이터를 byte 데이터로 저장하는 방법입니다. byte 데이터를 가져 와서 임시로 데이터를 char 데이터로 저장하려면 해당 특정 용도로 설계된 인코딩이 필요합니다. 다행히도 이러한 것들이 존재합니다. Wikipedia에는 ​​fairly comprehensive list 옵션이 있습니다. :-)

.NET Framework 내에서 가장 간단하고 액세스하기 쉬운 옵션은 Convert.ToBase64StringConvert.FromBase64String을 통해 노출되는 MIME Base-64 인코딩입니다.

관련 문제