Téléchargement
illégal
Posez votre question Signaler

[java] code ascii d'un char mais en unicode 8 [Résolu]

sbouli 171Messages postés 20 décembre 2007Date d'inscription 13 décembre 2011Dernière intervention - Dernière réponse le 10 sept. 2008 à 09:36
Bonjour,
Je cherche pour décompresser une chaine codée en lzw, à obtenir le code ascii d'un caractère, pour le moment si je fait :
public static int toASCII(char lettre)
{
return (int)lettre;
}
il me retourne la valeur unicode sur 16 bits et pas 8 bits par exemple Ä renvoi 65533 et pas 257 ...
évidement la chaine étant encodé par différent language (les clients varies) il faut que je puisse travailler en UTF 8
J'ai essayé de convertir ma string dès le départ avec :
byte[] utf8Bytes = txt2decode.getBytes("UTF8");
txt2decode = new String(utf8Bytes, "UTF8");
mais ça n'a rien changé ... pour infos ma boucle à cette tête :
String[] splitStr = txt2decode.split("") ;
for (i = 0 ; i < length ; i++) {
String current = splitStr [i] ;
int code = toASCII(txt2decode.charAt(i));
.....
}
Merci d'avance.
Stéphane
Lire la suite 

[java] code ascii d'un char mais en unicode 8 »

Suggestions
12 réponses
Réponse
+2
moins plus
Une petite fonction utile qui imprime les octets d'une chaîne en fonction de l'encodage choisi..
NB ici la conversion des byte java -128..127 en 0..255 (int) se fait implicitement par la lecture avec read() dans un flux ByteArrayInputStream.

import java.io.*;
import java.util.*;

public class StringEncodings
{
public static void printBytes (String s, String charsetName) throws UnsupportedEncodingException
{
int length = s.length ();

byte[] bytes = s.getBytes (charsetName);
ByteArrayInputStream in = new ByteArrayInputStream (bytes);

int byte255;
while ((byte255 = in.read ()) != -1)
{
System.out.print (byte255 + " ");
}
System.out.println();
}

public static void main (String[] args) throws UnsupportedEncodingException
{
printBytes ("ÂÄÔÖÎÛÜ", "ISO-8859-1"); // encodage occidental
printBytes ("ÂÄÔÖÎÛÜ", "UTF-16");
printBytes ("ÂÄÔÖÎÛÜ", "UTF-8");
}

}
Ajouter un commentaire
Réponse
+1
moins plus
Hello,

En fait je me suis mal expliqué ... je cherche à décompresser des strings compressées en utilisant l'algo de compression LZW. Pour le moment la compression à lieu en FLASH Action Script 3.
Or lors de la décompression en flash de la même chaine, lorsque j'arrive sur un caractère type ã (ou Ä) j'obtiens avec la fonction var code:int = txt2decode.charCodeAt(i) ;
des codes > 255 c'est même tout l'intéret de l'algo.
Lorsqu'il trouve des séquences identique, il leur attribue une place dans le dico et met dans la chaine l'index de cette séquence dans le dico. par exemple "<c" est inséré dans le dico en position 257 et le caractère dont le code "ascii" correspond à 257 est inséré dans la string compressée.

toute la difficulté est de convertir la fonction AS3 (flash 9) charCodeAt() en java ...

Voici le code compression/decompression en flash as3 :


         //conversion en AS3 de l'algorythm de Zeh Fernando version 1.0.0
	
	public class LZW {
		
		static var headerversion:String = "v1.0";
		
		// ===============================================================
		// COMPRESSION function -------------------------------------
		public static function compress (txt2encode:String): String {
			
			var dico:Array = new Array() ;
			for ( var i:int =0 ; i<256 ; i++)    dico[ String.fromCharCode (i) ] = i ;
			var result:String = "";
			var splitStr:Array = txt2encode.split("") ;
			var length:int = splitStr.length ;
			var nbChar:int = 257 ; // Nombres de caractères courant dans le dictionnaire
			var buffer:String = "" ; // initialisation du tampon buffer
			
			for (i=0 ; i <= length  ; i++) {
             	var current = splitStr[i] ;
				if ( dico[ buffer + current ] !== undefined ) {
					buffer += current ;
				} else {
					result += String.fromCharCode ( dico[buffer] ) ;
					dico [buffer + current] = nbChar++;
					buffer = current ;
				}
			}
			return (headerversion+result);
		}
		// ===============================================================
		// FAST DECOMPRESSION function -----------------------------------
		public static function decompress (txt2decode:String): String {
			
			txt2decode = txt2decode.substring(headerversion.length);// on supprime le  header "v1.0"
			
			var dico:Array = new Array() ;
			for ( var i:int =0 ; i<256 ; i++) {
				var c:String = String.fromCharCode (i) ;
				dico[c] = c ;
			}
			var splitStr:Array = txt2decode.split("") ;
			var length:int = splitStr.length ;
			var nbChar:int = 257; // nombre de caractère courant dans le dictionnaire
			var buffer:String = "" ; // initialisation du tampon mémoire
			var chaine:String = "" ; // chaine temporaire
			var result:String = "" ; // chaine retournée à la fin de la décompression
			for (i = 0 ;  i < length ; i++) {
				var current:String = splitStr [i] ;
				var code:int = txt2decode.charCodeAt(i) ;
				
				//trace("code "+code+" "+splitStr[i]);
				
				if (buffer == "") {
					buffer = current ;
					result += current ;
				} else {
					if ( code <= 256 ) {
						result += current ;
						chaine = buffer + current ;
						dico[nbChar] = chaine ;
						nbChar ++ ;
						buffer = current ;
					} else {
						chaine = dico [code] ;
						result += chaine ;
						dico [nbChar] = buffer + chaine.slice (0, 1);
						nbChar ++ ;
						buffer = chaine ;
					}
				}
			}
			return result;
		}
		// ===============================================================
	
	
	}//public class LZW




Pour infos, l'exemple de chaine que je compresse est :
"<call>
<cmd>login</cmd>
<callback>login</callback>
<id_membre>255</id_membre>
<id_site>0</id_site>
<pseudo>toto</pseudo>
</call>"

qui devient quelque chose comme (je suis pas sûr que le debugger + le copier/coller préserve les caractères ...) :

<call>āmd>login</cċĆĈāălbackčďđēĂĄĜĞėĉid_membre>255ēĪĬĮİIJćĩīsitIJ0ķĿŁļĘpseudo>toőēŊŌŎĆģĚ>"""


Merci pour ton aide !!
Ajouter un commentaire
Réponse
+0
moins plus
Il me semble que java travaille en interne avec des caractères UTF-16. Donc, le code d'un caractère d'une chaîne java est renvoyé en UTF-16.

C'est une bonne idée de travailler à partir d'un tableau d'octets grâce à getBytes ("UTF8");
Mais il ne faut pas reconvertir ce tableau en chaîne, car java semble alors les retraduire implicitement en UTF16

As-tu essayé tout simplement :

int length = txt2decode.length();
byte[] utf8Bytes = txt2decode.getBytes ("UTF8");
for (int i = 0; i < length; i++)
{
int code = utf8Bytes[i];
...
}
Ajouter un commentaire
Réponse
+0
moins plus
bonjour,

bizarrement, il me renvoi -61 pour le Ä .... mais on progresse :)

Merci
Ajouter un commentaire
Réponse
+0
moins plus
Tu as un tableau de bytes. Les bytes java sont codés de -128 à 128, je crois.
Il faut peut-être les convertir avec l'opération & 0xff pour les rétablir dans la tranche entre 0..255

Essaie ça et dis-moi :


int length = txt2decode.length();
byte[] utf8Bytes = txt2decode.getBytes ("UTF8");
for (int i = 0; i < length; i++)
{
int code = utf8Bytes[i] & 0xff;
...
}
sbouli- 5 sept. 2008 à 15:28
Hello,

Merci encore pour ton aide, malheureusement, j'ai essayé un peu tous les charsets sans résultat. Si je met UTF-8 (celui qui me parait le plus approprié), j'obtient -61 (sans le &0xff) pour le Ä ou 195 (avec le &0xff) alors que je voudrais 257 ....

ça m'agace ...

pour la souce du string, il vient pour le moment de clients en flash (CS 9) dont personne n'est capable de me dire en quel charset il est codé ...

Stéphane
in2ni - 8 sept. 2008 à 10:38
En essayant ma fonction, j'obtiens deux bytes pour le Ä en UTF-8 :
printBytes ("Ä", "UTF-8");
==> 195 132

Pourquoi cherches-tu as obtenir le byte 257 ? C'est impossible : on lit une chaîne d'octets, qu'on convertit dans la tranche 0..255, impossible donc d'avoir des valeurs supérieures à 255 !
sbouli- 8 sept. 2008 à 16:57
j'ai répondu plus bas dans le thread mais comme je suis pas sûr que tu reçoives un email, je répond aussi directement à ton post.

Stéphane
Ajouter un commentaire
Réponse
+0
moins plus
Tu as un tableau de bytes. Les bytes java sont codés de -128 à 128, je crois.
Il faut peut-être les convertir avec l'opération & 0xff pour les rétablir dans la tranche entre 0..255

Essaie ça et dis-moi :


int length = txt2decode.length();
byte[] utf8Bytes = txt2decode.getBytes ("UTF8");
for (int i = 0; i < length; i++)
{
int code = utf8Bytes[i] & 0xff;
...
}
Ajouter un commentaire
Réponse
+0
moins plus
finalement, c'est bon, ce code est bon, (au détail du dernier caractère près), le pb venait essentiellement du socket qui modifiait la string à la réception, j'ai tout passé en UTF-8 et ça tourne nickel !!!

Merci encore pour votre aide, ça m'a énormément fait avancer !!

Stéphane
Ajouter un commentaire
Ce document intitulé « [java] code ascii d'un char mais en unicode 8 » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Dossier à la une
Passage au tout numérique : quel coût pour les particuliers ?