2012-11-22 4 views
12

Je suis en train de convertir une chaîne encodée ISO 8859-1 en UTF-8.golang convertir iso8859-1 en UTF8

La fonction suivante fonctionne avec mon testdata qui contient tréma allemand, mais je ne suis pas tout à fait sûr de ce que la source codant pour la rune (b) cast suppose. Est-ce qu'il suppose une sorte de codage par défaut, par ex. ISO8859-1 ou est-il possible de lui dire quel encodage utiliser?

func toUtf8(iso8859_1_buf []byte) string { 
    var buf = bytes.NewBuffer(make([]byte, len(iso8859_1_buf)*4)) 
    for _, b := range(iso8859_1_buf) { 
     r := rune(b) 
     buf.WriteRune(r) 
    } 
    return string(buf.Bytes()) 
} 
+1

Par ailleurs, vous ne voulez iso8859-1, non? – ANisus

+0

oui, désolé de la confusion, je l'ai édité. – zeroc8

Répondre

12

rune est un alias pour int32, et en ce qui concerne le codage, une rune est supposé avoir une valeur de caractère Unicode (point de code). La valeur b dans rune(b) doit donc être une valeur Unicode. Pour 0x00 - 0xFF, cette valeur est identique à Latin-1, vous n'avez donc pas à vous en soucier.

Ensuite, vous devez encoder les runes en UTF8. Mais ce codage est simplement fait en convertissant un []rune en string.

Voici un exemple de votre fonction sans utiliser le package octets:

func toUtf8(iso8859_1_buf []byte) string { 
    buf := make([]rune, len(iso8859_1_buf)) 
    for i, b := range iso8859_1_buf { 
     buf[i] = rune(b) 
    } 
    return string(buf) 
} 
+0

Je pensais que seules les valeurs jusqu'à 0x7f étaient identiques, merci de le signaler. – zeroc8

+2

Les valeurs Unicode et Latin-1 sont identiques (Latin-1 peut être considéré comme le 0x00 - sous-ensemble 0xFF d'Unicode). Mais lorsque vous stockez la valeur, Latin-1 utilise seulement 1 octet (par exemple '0x41') tandis que Unicode utilise 4 octets (par exemple' 0x00000041'). Ce qui pourrait confondre est le codage UTF-8 où seulement 0x00 - 0x7F sont codés de la même manière que Latin-1, en utilisant un seul octet. – ANisus

+0

Les points de code UTF-8 n'existent pas. Voulez-vous dire unités de code UTF-8? –

2

L'effet de

r := rune(expression) 

est:

  • Déclarez la variable r de type rune (alias pour int32).
  • Initialiser variables r avec la valeur de expresion.

Aucun (re) encodage n'est impliqué et le fait de dire lequel devrait être utilisé en option n'est possible qu'en écrivant/manipulant explicitement un recodage dans le code. Heureusement, dans ce cas, aucun (ré) encodage n'est nécessaire, Unicode a incorporé ces codes de l'ISO 8859-1 d'une manière comparable à ASCII. (Si j'ai vérifié correctement here)

+0

Le réencodage est nécessaire. Les lettres comme ö ne sont pas codées de la même manière. Si vous avez la chaîne d'octets 'latin1 = [] byte {0x52, 0xE4, 0x76}', elle ne se convertira pas bien en chaîne. (Il est dit * Räv * en Latin-1) – ANisus

+2

Mais 0xE4 est vraiment 'ä', pas' ö' en ISO 8859-1: http://en.wikipedia.org/wiki/ISO/IEC_8859-1#Codepage_layout. Vérifiez-le ici: http://play.golang.org/p/s4TfzJUa7m – zzzz

+0

Ah, je pense que j'ai mal compris. Il est vrai qu'aucun réencodage n'est nécessaire entre Latin-1 et Unicode. Oui, la séquence d'octets indique Räv – ANisus