2015-09-11 21 views
7

Sto lavorando a un progetto in cui ho bisogno di convertire il testo da una codifica (ad esempio Windows-1256 in arabo) a UTF-8.Come convertire da una codifica a UTF-8 in Go?

Come faccio a fare questo in Go?

+0

Intendi una * codifica *? C'è solo * un * Unicode e l'arabo 1256 non è "un Unicode". – deceze

+0

Hai ragione, Iv ha modificato la domanda. Grazie. –

risposta

9

È possibile utilizzare the encoding package, che include il supporto per Windows-1256 tramite il pacchetto golang.org/x/text/encoding/charmap (nell'esempio qui sotto, importare questo pacchetto e utilizzare charmap.Windows1256 invece di japanese.ShiftJIS).

Ecco un breve esempio che codifica una stringa UTF-8 giapponese con la codifica ShiftJIS e quindi decodifica la stringa ShiftJIS su UTF-8. Sfortunatamente non funziona nel parco giochi poiché il parco giochi non ha i pacchetti "x".

package main 

import (
    "bytes" 
    "fmt" 
    "io/ioutil" 
    "strings" 

    "golang.org/x/text/encoding/japanese" 
    "golang.org/x/text/transform" 
) 

func main() { 
    // the string we want to transform 
    s := "今日は" 
    fmt.Println(s) 

    // --- Encoding: convert s from UTF-8 to ShiftJIS 
    // declare a bytes.Buffer b and an encoder which will write into this buffer 
    var b bytes.Buffer 
    wInUTF8 := transform.NewWriter(&b, japanese.ShiftJIS.NewEncoder()) 
    // encode our string 
    wInUTF8.Write([]byte(s)) 
    wInUTF8.Close() 
    // print the encoded bytes 
    fmt.Printf("%#v\n", b) 
    encS := b.String() 
    fmt.Println(encS) 

    // --- Decoding: convert encS from ShiftJIS to UTF8 
    // declare a decoder which reads from the string we have just encoded 
    rInUTF8 := transform.NewReader(strings.NewReader(encS), japanese.ShiftJIS.NewDecoder()) 
    // decode our string 
    decBytes, _ := ioutil.ReadAll(rInUTF8) 
    decS := string(decBytes) 
    fmt.Println(decS) 
} 

C'è un esempio più completo sul sito StackOverflow giapponese. Il testo è giapponese, ma il codice dovrebbe essere auto-esplicativo: https://ja.stackoverflow.com/questions/6120

+0

Non riesco a trovare un esempio live di conversione di una codifica in un'altra, farlo in dot net è facile ma qui sono davvero un principiante. –

+0

Grande esempio dal vivo. Hmm, quindi qui stiamo provando a convertire da UTF8 a giapponese SHIFTJIS, è possibile farlo saggio? –

+0

Per decodificare ShiftJIS, utilizzare la seconda parte, iniziando con "declare un decodificatore ...", encS è la stringa che si desidera decodificare, stringa (decBytes) è la stringa decodificata. Forse due funzioni sarebbero state migliori, ma volevo mantenere l'esempio il più breve possibile ... – rob74

2

Utilizzare i moduli da golang.org/x/text. Nel tuo caso questo sarebbe qualcosa del tipo:

b := /* Win1256 bytes here. */ 
dec := charmap.Windows1256.NewDecoder() 
// Take more space just in case some characters need 
// more bytes in UTF-8 than in Win1256. 
bUTF := make([]byte, len(b)*3) 
n, _, err := dec.Transform(bUTF, b, false) 
if err != nil { 
    panic(err) 
} 
bUTF = bUTF[:n] 
+0

Non sono molto abile in Go, ma allocare un buffer approssimativamente '* 2' mi sembra una pessima idea. Teoricamente, UTF-8 potrebbe essere quattro volte più grande della stringa di input (probabilmente mai in pratica però). – deceze

+0

È solo un esempio. La maggior parte dei caratteri in Win1256 [prendeva due byte] (http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit1256.txt) e nessuno ne richiede più di tre. Modificato. –

+0

Deve esserci un modo deterministico per dimensionare i buffer, non per l'ipotesi. La risposta di @ rob74 sembra mostrare un modo. – deceze