Décalage binaire, cho cho cho !

Décalage binaire, cho cho cho ! - Java - Programmation

Marsh Posté le 08-01-2003 à 09:45:01    

Salut à toi, qui vas m'aider.
Je cherche à écrire une classe réalisant un code binhex optimisé (j'avais posté ds un autre topic, un algo faisant ça, ms pas super otimisé l'algo). Pour cela, je cherche à me caler sur un algo de codage en base64 que g trouvé. Dans cet algo base64, voila les parties qui m'interressent:
 

Code :
  1. private final static char charCodes[] = {
  2.         'A','B','C','D','E','F','G','H',
  3.         'I','J','K','L','M','N','O','P',
  4.         'Q','R','S','T','U','V','W','X',
  5.         'Y','Z','a','b','c','d','e','f',
  6.         'g','h','i','j','k','l','m','n',
  7.         'o','p','q','r','s','t','u','v',
  8.         'w','x','y','z','0','1','2','3',
  9.         '4','5','6','7','8','9','+','/'
  10.     };
  11.     private byte encBuf[] = new byte[4];


 

Code :
  1. // encode triples for efficiency
  2.         while (pos + 2 < off + len) {
  3.             byte b0 = data[pos];
  4.             byte b1 = data[pos + 1];
  5.             byte b2 = data[pos + 2];
  6.             encBuf[0] = (byte)charCodes[((b0 >> 2) & 0x3f)];
  7.             encBuf[1] = (byte)charCodes[((b0 & 0x3) << 4)|((b1 >> 4) & 0xf)];
  8.             encBuf[2] = (byte)charCodes[((b1 & 0xf) << 2)|((b2 >> 6) & 0x3)];
  9.             encBuf[3] = (byte)charCodes[b2 & 0x3f];
  10.             out.write(encBuf);
  11.             encoded = 0;
  12.             col += 4;
  13.             if (col >= 76) {
  14.                 out.write('\n');
  15.                 col = 0;
  16.             }
  17.             pos += 3;
  18.         }


 
La partie des masques et décalages binaires, vous y comprenez qqch vous ? moi j'avoue que je suis largué. J'imagine que pour l'hexa c plus simple, mais je vois pas comment utiliser la même méthode que lui : un tableau contenant les caractères hexa, puis des masques et décalages binaires pour obtenir l'indice du signe héxa correspondant à la valeur de chaque byte.
Autre chose : dans cet algo, il caste en "byte" les "char" contenus dans "charCodes". ça fout pas le bordel ça !? J'croyais qu'en Java, les caractères était sur 2 octets !?


Message édité par El_gringo le 08-01-2003 à 09:46:43
Reply

Marsh Posté le 08-01-2003 à 09:45:01   

Reply

Marsh Posté le 08-01-2003 à 10:12:36    

recopier sans comprendre cai mal [:dawa]


Message édité par darklord le 08-01-2003 à 10:20:33

---------------
Just because you feel good does not make you right
Reply

Marsh Posté le 08-01-2003 à 10:19:41    

DarkLord a écrit :

recopier sans comprendre cai mail [:dawa]


 
Ben... justement, c pour ça que j'essaye de comprendre ! :sarcastic:

Reply

Marsh Posté le 08-01-2003 à 10:20:20    

El_gringo a écrit :


 
Ben... justement, c pour ça que j'essaye de comprendre ! :sarcastic:  


 
 :jap:  


---------------
Just because you feel good does not make you right
Reply

Marsh Posté le 08-01-2003 à 10:25:00    

Et sinon !? tu peux rien pr moi ?
au moins, tu comprends pourquoi il fait un cast d'un char en un byte ? ça devrait faire n'imp ça, non ?

Reply

Marsh Posté le 08-01-2003 à 11:05:51    

Yesss, c bon.
Voila ma méthode de convertion :

Code :
  1. private final static char charCodes[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};


 

Code :
  1. public void write (byte b[], int off, int len) throws IOException {
  2.         byte[] encBuf = new byte[1];
  3.         while (off < len) {
  4.             // obtenir la partie haute de l'octet courant
  5.             byte bCurrent  = b[off];
  6.             encBuf[0] = (byte)charCodes[(bCurrent & 0xf0) >> 4] ;
  7.             encBuf[1]  = (byte)charCodes[ bCurrent & 0x0f];
  8.             out.write(encBuf);
  9.             m_col++;
  10.             if (m_col >= 73) {
  11.                 out.write('\n');
  12.                 m_col = 0;
  13.             }
  14.             off++;
  15.         }
  16.     }


Message édité par El_gringo le 08-01-2003 à 11:16:42
Reply

Marsh Posté le 08-01-2003 à 11:15:48    

il me fait un peu peur ton \n ...


---------------
Just because you feel good does not make you right
Reply

Marsh Posté le 08-01-2003 à 11:25:19    

DarkLord a écrit :

il me fait un peu peur ton \n ...


 
'faut pas être craintif comme ça ! :D  
Non, ms sérieusement, pourquoi il te fait peur ce '\n' ?
'faudra que je vérifie la norme de codage binhex, mais les colones de 72 octets, c'est la norme de codage Base64.
Oups, j'ai remplacé m_col++ par m_col += 2; (ça sera mieux !)

Reply

Marsh Posté le 08-01-2003 à 11:28:10    

Donc, finalement, ma méthode de codage :

Code :
  1. public void write (byte b[], int off, int len) throws IOException {
  2.         byte[] encBuf = new byte[2];
  3.         while (off < len) {
  4.             // obtenir la partie haute de l'octet courant
  5.             byte bCurrent  = b[off];
  6.             encBuf[0] = (byte)charCodes[(bCurrent & 0xf0) >> 4] ;
  7.             encBuf[1]  = (byte)charCodes[ bCurrent & 0x0f];
  8.             out.write(encBuf);
  9.             m_col += 2;
  10.             if (m_col >= 73) {
  11.                 out.write('\n');
  12.                 m_col = 0;
  13.             }
  14.             off++;
  15.         }
  16.     }

Reply

Marsh Posté le 08-01-2003 à 11:34:12    

El_gringo a écrit :

Autre chose : dans cet algo, il caste en "byte" les "char" contenus dans "charCodes". ça fout pas le bordel ça !? J'croyais qu'en Java, les caractères était sur 2 octets !?


 
Je crois pas que ça tienne sur 2 octets. 2 octets, c'est pour l'Unicode. Dans la classe String, effectivement, j'ai entendu dire que tout était encodé en Unicode mais je peux me tromper, j'ai pas vérifié. Mais un char est bêtement codé sur 1 octet.
Mais sinon, le cast n'a rien de bordélique ; tu peux faire la même chose avec des int :
int a = 56;
char c = (char)a;
System.out.println(c); // écrit le caractère ayant pour numéro ASCII 56
 
Donc byte, int, char sont castables assez facilement entre eux. Il y a certainement des utilisations qui pourraient engendrer des bugs mais là à brûle-pourpoint (j4adore cette expression :D) je vois pas.

Reply

Marsh Posté le 08-01-2003 à 11:34:12   

Reply

Marsh Posté le 08-01-2003 à 11:39:39    

Taiche a écrit :


 
Je crois pas que ça tienne sur 2 octets. 2 octets, c'est pour l'Unicode. Dans la classe String, effectivement, j'ai entendu dire que tout était encodé en Unicode mais je peux me tromper, j'ai pas vérifié. Mais un char est bêtement codé sur 1 octet.
Mais sinon, le cast n'a rien de bordélique ; tu peux faire la même chose avec des int :
int a = 56;
char c = (char)a;
System.out.println(c); // écrit le caractère ayant pour numéro ASCII 56
 
Donc byte, int, char sont castables assez facilement entre eux. Il y a certainement des utilisations qui pourraient engendrer des bugs mais là à brûle-pourpoint (j4adore cette expression :D) je vois pas.


 
Un char en Java, c'est 2 octets...
Mais en fait, là, c pas gênant, parce qu'on a le contrôle sur les caractères qui vont être encodés (uniquement ceux contenus dans le tableau charCodes[] et avec là, ça pose pas de pb apparement, un seul octet suffit. Ms sinon, avec d'autre caractères, je suis quasi sur qu'un cast d'un char en byte peut fouttre la merde (car perte de données possible)

Reply

Marsh Posté le 08-01-2003 à 12:17:14    

El_gringo a écrit :


Un char en Java, c'est 2 octets...


 

Citation :

char, whose values are 16-bit unsigned integers representing Unicode characters.


 
Ah ba OK, autant pour moi :o

Reply

Marsh Posté le 08-01-2003 à 13:42:22    

bin simplement que ton retour à la ligne n'est pas OS-indépendent quoi :o
 
J'aurais fait plutôt
 

Code :
  1. private static final String NEW_LINE = System.getProperty("line.separator" );


blba bla
 

Code :
  1. out.write(NEW_LINE);


 
ca aurait été plus propre il me semble :o


Message édité par darklord le 08-01-2003 à 14:28:38

---------------
Just because you feel good does not make you right
Reply

Marsh Posté le 08-01-2003 à 14:27:37    

Ha, ouais, t'as raison.
Sauf qu'en l'occurence, out est un OutputStream (je rappelle que mon truc est un FilterOutputStream. Du coup "out.write (NEW_LINE)", c pas possible, ça sera plutôt out.write (NEW_LINE.getBytes()).
Merci de m'y avoir fait penser !

Reply

Marsh Posté le 08-01-2003 à 14:28:56    

Ha, au passage : j'demandais s'il existait pas une OutputStream qui permettait d'écrire dans une String, une espèce ce StringBufferOutputStream
du coup, je me débrouille avec un ByteArrayOutputStream, dont j'utilise la méthode toString().

Reply

Marsh Posté le 09-01-2003 à 03:40:31    

El_gringo a écrit :

Ha, au passage : j'demandais s'il existait pas une OutputStream qui permettait d'écrire dans une String, une espèce ce StringBufferOutputStream
du coup, je me débrouille avec un ByteArrayOutputStream, dont j'utilise la méthode toString().


Dans une String c'est impossible (elle sont immuables en Java, tu as donc intérêt à préserver leur unicité et à utiliser == dessus aussi souvent que possible).
 
Par contre, vers un StringBuffer ça me paraît hautement probable que ça existe.
bingo :
http://java.sun.com/j2se/1.4.1/doc [...] riter.html
http://java.sun.com/j2se/1.4.1/doc [...] eader.html

Reply

Marsh Posté le 09-01-2003 à 08:02:05    

nraynaud a écrit :


Dans une String c'est impossible (elle sont immuables en Java, tu as donc intérêt à préserver leur unicité et à utiliser == dessus aussi souvent que possible).


 :ouch:

Reply

Marsh Posté le 09-01-2003 à 08:52:13    

nraynaud a écrit :


Dans une String c'est impossible (elle sont immuables en Java, tu as donc intérêt à préserver leur unicité et à utiliser == dessus aussi souvent que possible).
 
Par contre, vers un StringBuffer ça me paraît hautement probable que ça existe.
bingo :
http://java.sun.com/j2se/1.4.1/doc [...] riter.html
http://java.sun.com/j2se/1.4.1/doc [...] eader.html


 
Ben oui, mais bon, un Writer, c'est pas une OutputStream. Je connais StringWriter... c pour ça qu'a un moment, j'demandais comment on pouvait passer d'un Writer à une OutpuStream. Dans l'autre sens (OutpuStream -> Writer), ça roule, grâce au OutputStreamWriter, mais apparement, y a rien qui offre le contraire (un WriterOutputStream par exemple). Ms bon, ma solution marche nickel, et je suis bien content du petit BinhexOutputStreamFilter que g écrit ! :D

Reply

Marsh Posté le 09-01-2003 à 11:04:31    


juste pour commenter mon  :ouch:, j'ajouterais que ca ne sert vraiment à rien de faire un == dessus. Si tu regardes le source de la classe String, c'est premier test qu'ils font  :  

Code :
  1. public boolean equals(Object anObject) {
  2. if (this == anObject) {
  3.     return true;
  4. }
  5.         ...
  6.     }

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed