[java] code ascii d'un char mais en unicode 8
Résolu
sbouli
Messages postés
208
Statut
Membre
-
sbouli Messages postés 208 Statut Membre -
sbouli Messages postés 208 Statut Membre -
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
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
A voir également:
- [java] code ascii d'un char mais en unicode 8
- Code ascii - Guide
- Clé windows 8 - Guide
- Jeux java itel - Télécharger - Jeux vidéo
- Waptrick java football - Télécharger - Jeux vidéo
- Comment déverrouiller un téléphone quand on a oublié le code - Guide
7 réponses
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 :
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 !!
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 !!
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];
...
}
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];
...
}
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;
...
}
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;
...
}
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
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;
...
}
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;
...
}
désolé mais toujours pas, il me renvoi 63 pour le Ä et pas 257
j'ai du mal à comprendre le coup du -128/+128 ....
voila mon code actuel pour la décompression LZW :
j'ai du mal à comprendre le coup du -128/+128 ....
voila mon code actuel pour la décompression LZW :
public static String decompress(String txt2decode) throws UnsupportedEncodingException {
//txt2decode2 = txt2decode.getBytes("UTF8");
txt2decode = txt2decode.substring(headerversion.length());// on supprime le header "v1.0"
Map dico = new HashMap() ;
Integer i;
for ( i =0 ; i<256 ; i++) dico.put(toChar(i), toChar(i));
int length = txt2decode.length();
byte[] utf8Bytes = txt2decode.getBytes("ISO-8859-1");
//String[] splitStr = txt2decode.split("") ;
//int length = splitStr.length ;
int nbChar = 257; // nombre de caractère courant dans le dictionnaire
String buffer = "" ; // initialisation du tampon mémoire
String chaine = "" ; // chaine temporaire
String result = "" ; // chaine retournée à la fin de la décompression
for (i = 0 ; i < length ; i++) {
//String current = splitStr [i] ;
//int code = toASCII(txt2decode.charAt(i));
int code = utf8Bytes[i]& 0xff;
String current = ""+toChar(code);
if (buffer == "") {
buffer = current ;
result += current ;
} else {
if ( code <= 256 ) {
result += current ;
chaine = buffer + current ;
dico.put(nbChar, chaine);
nbChar ++ ;
buffer = current ;
} else {
chaine = (String) dico.get(code);
result += chaine ;
dico.put(nbChar, buffer + chaine.substring(0, 1));
nbChar ++ ;
buffer = chaine ;
}
}
}
return result;
}
Je m'aperçois que tu utilises
byte[] utf8Bytes = txt2decode.getBytes("ISO-8859-1");
ce ne serait pas plutôt
byte[] utf8Bytes = txt2decode.getBytes("UTF-8");
Si Ä n'est pas connu dans un charset (jeu de caractère), il sera interprété comme '?' (code 63 !)
Par exemple :
bytes[] b = "Ä".getBytes("US-ASCII");
System.out.println (b[0] & 0xff); ==> affichera 63
Généralement, les langages considèrent le byte (octet) comme un entier positif dont la valeur peut être comprise entre 0 et 255. Mais les concepteurs de java ont décidé qu'il s'agissait d'un entier signé, dont la valeur minimale commence à -128 et la valeur maximale est à +127. C'est une convention, mais pour faire correspondre des bytes (et non pas des char) avec les valeurs ASCII habituelles (0..255), il ne faut pas oublier de les convertir en entiers non signés, grâce à & 0xff.
Je testerai ton programme demain. Mais essaie de changer le charset utilisé dans la création de ton tableau de bytes en utilisant getBytes("UTF-8"), si tu es bien sûr que ta chaîne d'origine est de l'UTF-8, évidemment (à vérifier !)
byte[] utf8Bytes = txt2decode.getBytes("ISO-8859-1");
ce ne serait pas plutôt
byte[] utf8Bytes = txt2decode.getBytes("UTF-8");
Si Ä n'est pas connu dans un charset (jeu de caractère), il sera interprété comme '?' (code 63 !)
Par exemple :
bytes[] b = "Ä".getBytes("US-ASCII");
System.out.println (b[0] & 0xff); ==> affichera 63
Généralement, les langages considèrent le byte (octet) comme un entier positif dont la valeur peut être comprise entre 0 et 255. Mais les concepteurs de java ont décidé qu'il s'agissait d'un entier signé, dont la valeur minimale commence à -128 et la valeur maximale est à +127. C'est une convention, mais pour faire correspondre des bytes (et non pas des char) avec les valeurs ASCII habituelles (0..255), il ne faut pas oublier de les convertir en entiers non signés, grâce à & 0xff.
Je testerai ton programme demain. Mais essaie de changer le charset utilisé dans la création de ton tableau de bytes en utilisant getBytes("UTF-8"), si tu es bien sûr que ta chaîne d'origine est de l'UTF-8, évidemment (à vérifier !)
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
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
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");
}
}
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");
}
}