Share |

sabato 12 giugno 2010

Java: Codifica e Decodifica Esadecimale

In questo articolo Java verrà mostrato un componente, da me creato ad hoc, per compiere le operazioni di codifica e decodifica esadecimale di stringhe di testo.

L'utilizzo della base esadecimale per la lavorazione ed il controllo di dati e buffer di dati è abbastanza normale e diffusa, soprattutto quando si adoperano connettori a risorse esterne ed in casi di attraversamento di diversi strati software.

Si utilizza questa trasformazione, per esempio, al fine di verificare che i caratteri che si stanno per scrivere in un campo del DB Server IBM DB2 non contengano i valori LOW-VALUE(in esadecimale X'00') e HIGH-VALUE(in esadecimale X'FF').

Questi caratteri possono provocare la troncatura dei dati al momento della loro estrazione, sebbene sia i LOW-VALUES che i HIGH-VALUES, siano dei caratteri che possono essere, al pari di tutti gli altri caratteri, salvati ed utilizzati in campi del DB.


La Classe HexEncoder

Il componente che sto per presentare è tanto semplice quanto comodo e funzionale.

Si tratta di una semplice classe base che brucia uno StringBuffer codificandolo e decodificandolo in un altro buffer esadecimale privo dei caratteri LOW e HIGH VALUES, eventualmente presenti nel buffer in ingresso.

Per convenzione, si decide che ogni carattere trasformato in esadecimale ha una lunghezza fissa e predefinita, a piacimento.

package org.ma.decode;

/**
 * Brucia uno StringBuffer codificandolo o de-codificandolo 
 * in sequenze esadecimali prive dei caratteri LOW e HIGH VALUES, 
 * eventualmente presenti nel buffer originale.
 * 
 * Per convenzione, è deciso che ogni carattere trasformato 
 * in esadecimale ha una lunghezza fissa e predefinita. 
 * 
 * @author mirko Agrati
 */
public final class HexEncoder {
  /**
   * Lunghezza che ogni sequenza esadecimale deve avere 
   * per rappresentare un carattere.
   */
  private static final int HEX_SEQUENCE_LENGHT = 34; 
 
  /** Rappresentazione Java del carattere LOW_VALUE. */ 
  private static final char HEX_LOW_VALUE = '\u0000';

  /** Rappresentazione Java del carattere HIGH_VALUE. */
  private static char HEX_HIGH_VALUE = '\uFFFF';
 
  /**
   * Codifica un buffer restituendolo in formato esadecimale 
   * e senza caratteri LOW e HIGH VALUE.
   * 
   * @param in  Il buffer da codificare
   * @return    Un buffer con codifica esadecimale
   */
  public final static StringBuffer encode(StringBuffer in){
    StringBuffer out = new StringBuffer();
  
    for(int i=0; i<in.length(); i++){
      char c = in.charAt(i);
      if( c != HEX_LOW_VALUE && c != HEX_HIGH_VALUE )
        out.append(charToHex(c));
    }
  
    return out;
  }
 
  /**
   * Decodifica un buffer esadecimale restituendolo in formato leggibile.
   * Ogni sequenza di {@link #HEX_SEQUENCE_LENGHT} caratteri esadecimali 
   * rappresenta un carattere leggibile. 
   * 
   * @param inHex  Il buffer esadecimale da de-codificare;
   * @return       Uno StringBuffer con contenuto leggibile.
   */
  public final static StringBuffer decode(StringBuffer inHex){
    StringBuffer out = new StringBuffer();
  
    for(int i=0; i<inHex.length(); i++){
      char c = ' ';
      String t = "";
   
      for(int j=0;j<HEX_SEQUENCE_LENGHT;j++){
        if(i+1 <= inHex.length()){
          c = inHex.charAt(i);  
          t += ( c != HEX_LOW_VALUE && c != HEX_HIGH_VALUE && c != '0')
                    ? ""+ c : "";
          i++;
        }
      }
      out.append((char)Integer.parseInt(t,16));
    }
   
    return out;
  }
 
 /**
  * Trasforma un carattere in una sequenza esadecimale 
  * di lunghezza predeterminata pari al valore della
  * costante {@link #HEX_SEQUENCE_LENGHT}.
  * 
  * @param c Il carattere che deve essere codificato.
  * @return La sequenza esadecimale generata 
  *          codificando il parametro c.
  */
 private static String charToHex(char c){
  String t = Integer.toHexString(c);
  
  while(t.length() < HEX_SEQUENCE_LENGHT)
   t = "0" + t;
  
  return t;
 }
 
 public static void main(String[] args){
  StringBuffer test = new StringBuffer("Ciao, sono la Stringa di test! :)");
  StringBuffer buffer = HexEncoder.encode(test);

  System.out.println("ORIGINALE :\n" + test + "\n\n\n");
  System.out.println("ENCODING :\n" + buffer + "\n\n\n");
  System.out.println("DECODING :\n" + HexEncoder.decode(buffer));
  
 }
}

Conclusioni

Come premesso, la classe è semplice ed il suo funzionamento trasparente all'utilizzatore. Come è possibile testare, ed immaginare, agendo sul numero di byte che ogni carattere deve contenere per la sua rappresentazione esadecimale, in questa maniera i buffer esadecimali mutano la loro lunghezza rispetto alla stringa in ingresso. Solitamente utilizzo la classe per ritornare ad avere lo StringBuffer iniziale ripulito però dai suddetti caratteri in eccesso. Tra l'altro la classe si presta a facili implementazioni e modifiche per parsare altri tipi di dati aumentandone notevolmente le funzionalità. Alla prossima, MA

0 commenti:

Posta un commento

Non ti è chiaro qualcosa?
No problem, posta il tuo dubbio ;)

..... e ricordati di firmarlo!