2015-11-16 2 views
1

exécutant le code suivant semble générer les valeurs erronées:Pourquoi l'encodage Android Shift-JIS du symbole Yen (U + 00A5) produit -4, -4?

byte[] data = "\u00a5".getBytes("Shift_JIS"); 

Il produit [-4, -4], mais je pense [0x5c]

J'ai essayé plusieurs noms alternatifs, « Shift -JIS "," shift_jis "," cp932 "et tous produisent le même résultat.

Quand je nourris les données obtenues dans le décodeur Shift-JIS, je reçois une exception: java.nio.charset.UnmappableCharacterException: Length: 2

C'est, avec le décodeur configuré comme suit:

Charset charset = Charset.forName("Shift_JIS); 
     CharsetDecoder decoder = charset.newDecoder() 
       .onMalformedInput(CodingErrorAction.REPORT) 
       .onUnmappableCharacter(CodingErrorAction.REPORT); 

Mais compte tenu de la sortie du l'encodeur a l'air faux, je suppose que le décodeur n'est pas pertinent. Mon point est que, indépendamment des octets réels, le codeur génère des données qu'il ne peut pas décoder.

Le Yen pleine largeur (U + FFE5) est codé en [-127 (0x81), -113 (0x8F)] et se décode correctement. Bizarrement, si j'essaie de décoder [92 (0x5C)] ce que je pense être le codage Shift-JIS du Yen simple largeur, le décodeur Android/Java produit une barre oblique inverse, laissant le caractère 92.

Si le codeur ne prenait pas en charge un caractère donné, je m'attendrais à un caractère de remplacement tel que '?'. Mais -4 (0xFC) ne semble même pas être valide Shift-JIS. Ce n'est même pas le caractère de remplacement Unicode U + FFFD. En utilisant la ligne suivante, je peux voir que le codeur semble être configuré pour utiliser [-4, -4]:

Charset.forName("Shift_JIS").newEncoder().replacement() 
  • Alors pourquoi n'est pas le Yen simple largeur cartographié dans Shift-JIS?
  • Est-ce que [-4, -4] est un remplacement d'encodeur sensible?
  • Pourquoi le décodeur ne supporte-t-il pas le mappage 0x5C vers Yen (U + 00A5)?
  • Si 0x5C n'est pas le codage correct, qu'est-ce que c'est?

Répondre

1

Une réponse partielle: retour lorsque Microsoft a créé son Est-Asie pages de code pour Windows, comme la page de code japonais 932 et coréen 949, ils ont fait l'octet 0x5C render comme symbole monétaire (soit un signe Yen ou Won signe respectivement) tout en agissant syntaxiquement comme un caractère de barre oblique inverse dans les chemins de fichiers (de sorte qu'un chemin de fichier sur un système japonais pourrait ressembler

C:¥Documents¥something.doc 

). Ainsi, l'octet était en un sens un signe Yen, mais aussi, dans un certain sens, un antislash; le même octet a même été rendu comme un différent de ces symboles en fonction de la police lorsque sur un système japonais, selon http://archives.miloush.net/michkap/archive/2005/09/17/469941.html.

L'absence d'un sens uniforme du symbole dans le codage signifie que si un codeur Shift-JIS peut cartographier sensiblement les deux \ et ¥ à l'octet 0x5C, un décodeur essayant de mapper un Shift-JIS- chaîne codée à une séquence de points de code unicode n'a aucun moyen de savoir s'il faut convertir l'octet 0x5C en une barre oblique inverse ou en un signe yen; Les utilisateurs japonais faisaient ce choix via leur sélection police (s'ils étaient capables de le faire). Face à cette ambiguïté irréversible, tous les décodeurs semblent choisir de décoder 0x5C en antislash. (Au moins, Python fait cela, et the WhatWG have a spec that dictates it.)

En ce qui concerne les détails de ce que font en particulier Java/Android lorsqu'on leur demande de coder un signe Yen en shift_jis, je crains de ne pas savoir.