2017-04-18 1 views
0

golang 문자열의 특정 16 진 값을 이스케이프 처리하려고합니다. 함수 호출은 다음과 같습니다.문자열 리터럴의 16 진수 값 이스케이프 처리

Insert(0, "\x00\x00\x00\rIHDR\x00\x00\x000\x00\x00\x000\b\x03") 
Insert(25, "\x00\x00\x00\x06PLTE") 
Insert(43, "\x00\x00\x00\x02tRNS") 
Insert(57, "\x00\x00\t;IDATx\xDA\x010\t\xCF\xF6") // problem line 
Insert(2432, "\x00\x00\x00\x00IEND") 

"xD"16 진수 이스케이프를 해석 할 때 문제가 발생합니다. 정확하게 Ú 값으로 이스케이프하는 대신 (대체 문자)로 이스 케이 핑됩니다. ,

fmt.Println("\xDA") 
i := 218 
h := fmt.Sprintf("%x", i) 
fmt.Printf("Hex conf of '%d' is '%s'\n", i, h) 
fmt.Println(string(i)) 

이 조각이 때 실행 인쇄

� 
Hex conf of '218' is 'da' 
Ú 

내가 여기서 뭔가를 놓치고 있습니까 :

나는이 다음과 놀이터의 예에서 발생하는 무슨이다 보장? "\ xDA"가 65533의 값으로 이스케이프되고 있다는 사실은 CRC32와 다른 체크섬에 의존하는 전체 프로그램을 버리고 있습니다. 이것은이 프로그램의 javascript version에서 발생하지 않습니다 (그 자체는 C로 작성된 James compface 프로그램의 번역입니다). https://play.golang.org/p/c-XMK68maX

+0

'\ xDA'이 유효한 진수 이스케이프를 _is_ :

다음은 run on the Playground 수있는 예시입니다. 'rune (218)'의 utf8 인코딩은'\ xc3 \ x9a'입니다.네가 여기서 무슨 일이 일어날 지 모르겠다. – JimB

+0

나는 실수를 할 수는 있었지만 'fmt.Println ("\ xDA")'가' ''대신에 'Ú'을 출력 할 것을 기대하고 있었다. –

답변

3

이동 문자열은 일련의 바이트이지만 인코딩이 필요할 때, UTF8로 가정한다. 값 \xda이 유효한 UTF8 문자가 아닌, 그래서이 unicode.ReplacementCharacter ""

ReplacementChar = '\uFFFD'  // Represents invalid code points. 

로 변환있어 인쇄 할 때 문자열 리터럴에서 \xda의 룬 값을 원하는 경우에 사용하는 유니 코드 이스케이프 : \u00DA, 또는 인코딩 된 utf8 (\xc3\x9a)을 사용하거나 문자 자체 : Ú을 사용하십시오. 당신이 실제로 당신의 문자열에 \xda의 단일 바이트 값을 원하는 경우

https://play.golang.org/p/EJZIqCI_Gr

, 그건 당신이 무엇을하고 인쇄 된 문자는 하찮은이다.

+0

고마워! 나는 방금 16 진수 값을 유니 코드 (포스트 후 몇 분)로 변경하는 것을 끝내었고 모든 것이 원활하게 진행되었다.) –

1

귀하의 입력이 ISO-8859-1 (라틴-1)과 같다 : 여기

는 놀이터의 링크입니다. UTF-8로 변환하십시오. 예를 들어,

package main 

import (
    "fmt" 
    "unicode/utf8" 
) 

// ISO88591ToString maps ISO-8859-1 (Latin-1) to string (UTF-8). 
func ISO88591ToString(iso string) string { 
    var utf []rune 
    for i := 0; i < len(iso); i++ { 
     r := iso[i] 
     if utf == nil { 
      if r < utf8.RuneSelf { 
       continue 
      } 
      utf = make([]rune, len(iso)) 
      for j, r := range iso[:i] { 
       utf[j] = rune(r) 
      } 
     } 
     utf[i] = rune(r) 
    } 
    if utf == nil { 
     return string(iso) 
    } 
    return string(utf) 
} 

func main() { 
    l1 := "\x00\x00\t;IDATx\xDA\x010\t\xCF\xF6" 
    fmt.Printf("%q\n", l1) 
    s := ISO88591ToString(l1) 
    fmt.Printf("%q\n", s) 
} 

출력 :

"\x00\x00\t;IDATx\xda\x010\t\xcf\xf6" 
"\x00\x00\t;IDATxÚ\x010\tÏö" 
1

Go의 문자열은 UTF-8이며 \xDA은 유효한 UTF-8 시퀀스가 ​​아니므로 문자열 대신 U + FFFD 문자가 필요합니다. Ú 또는 U + 00DA).

그러나 원시 바이트로 작업하는 것처럼 보이므로 \u00DA으로 표시되는 룬을 UTF-8로 2 바이트 시퀀스 \xC3\x8F으로 인코딩할지 여부 또는 단일 바이트가 필요한지 여부를 고려해야합니다 \xDA. 전자는 원하는대로 2 바이트를 요구하는 Ú를 인쇄합니다. 후자는 예상대로 인쇄되지 않지만 정확히 \xDA은 2 바이트가 아닌 1 바이트로 해석됩니다.

func main() { 
    // A string made up of UTF-8 lead bytes. 
    dataString := "\xCF\xDA\xF6" 

    // Doesn't print what you think it should. 
    for _, c := range dataString { 
     fmt.Printf("%X ", c) 
    } 
    fmt.Println() 

    // Convert the string's bytes to a byte slice. 
    data := []byte(dataString) 

    // Now it should print CF, DA, F6. 
    for _, b := range data { 
     fmt.Printf("%X ", b) 
    } 
    fmt.Println() 
}