venerdì 22 luglio 2011

Calcolo del CIN in java

Il codice ISIN è un codice internazionale per identificare univocamente gli strumenti finanziari. La struttura del codice e le regole per la sua assegnazione sono stabilite dall'ISO (International Organization for Standardization) nello standard ISO 6166.” (Fonte Banca D’Italia)

ISIN sta per International Securities Identification Number.
Per calcolare il CIN (Control Internal Number) si procede in questo modo:

1. Si concatena il codice nazione e le 9 cifre numeriche inserite dall’utente (con il padding degli zeri a sinistra nel caso siano inferiori a 9), si ottiene così una stringa di 13 caratteri;
2. Ogni cifra dispari nella stringa di 13 è moltiplicata per 2, le cifre così ottenute sono sommate per ottenere un totale di 3 cifre;
3. Al risultato ottenuto al punto 2 si sommano le cifre pari della stringa di 13;
4. Si esegue la differenza tra il numero 10 e la prima cifra a partire da destra del risultato del punto 3, questo è il CIN.

Quindi il codice ISIN sarà dato da IT+9cifre conto+CIN (ovviamente IT nel caso italiano).

Di seguito un esempio di codifica java, con due metodi pubblici che dato il numero conto (come stringa o come intero) calcolano il valore completo dell’ISIN:

1. public static String getIsin(int valoreConto);
2. public static String getIsin(String valoreConto);

 
public class ItalianIsin {

      private static final String ITALIAN_CODE="1829";
     
      /**
       * Torna l'ISIN sotto forma di Stringa contenente
       * IT- 9 cifre con padding degli 0 - CIN
       * @param valoreConto - intero
       * @return
       */
      public static String getIsin(int valoreConto){
            valida(valoreConto);
            String valConto=String.valueOf(valoreConto);
            return getIsin(valConto);
      }
      private static void valida(int valoreConto)
      {
            if(valoreConto>999999999) throw new IllegalArgumentException("Attenzione, il codice conto non può superare le nove cifre!");
          if(valoreConto<=0) throw new IllegalArgumentException("Attenzione, il codice Isin non può essere negativo o nullo");
      }
      /**
       * Torna l'ISIN sotto forma di Stringa contenente
       * IT- 9 cifre con padding degli 0 - CIN
       * @param valoreConto - Stringa
       * @return
       */
      public static String getIsin(String valoreConto){
            String valore1=getCodice(valoreConto,true);
            int totale1=getTotale(valore1);
            int totale2=addCifrePari(totale1, valore1);
            String  cin=getCin(totale2);
            StringBuffer isin=new StringBuffer();
            isin.append("IT");
            isin.append(getCodice(valoreConto, false));
            isin.append(cin);
            return isin.toString();
           
      }
      private static int getValoreProdotto(int val)
      {
            if(val>18)
            {
                  throw new IllegalArgumentException("Attenzione, " +
                             " errore nel calcolo dell'algoritmo per il codice ISIN");
            }
            else
            {
            DecimalFormat d=new DecimalFormat("00");
            String valore=d.format(val);
            char[] list=valore.toCharArray();
            int primo=getIntFromChar(list[0]);
            int secondo=getIntFromChar(list[1]);
           
            return primo+secondo;
           
                 
            }
      }
      /**
       * Cicla sulle cifre dispari,
       * ogni cifra viene moltiplicata per 2
       * e vengono sommate le due cifre del risultato.
       * La somma del risultato così trovato per tutte le cifre
       * costituisce il TOTALE
       * @param theString
       * @return
       */
      private static int getTotale(String theString)
      {
            int totale=0;
            int valore=0;
            for(int i=0;i<theString.length();)
            {
                 
                        char s=theString.toCharArray()[i];
                       
                        valore=getIntFromChar(s)*2;
                        totale+=getValoreProdotto(valore);
                       
                 
                  i=i+2;
            }
            return totale;
      }
     
      private static int getIntFromChar(char c)
      {
            String s=String.valueOf(c);
            return Integer.valueOf(s);
      }
      /**
       * Al totale si sommano le cifre pari
       * @param totale
       * @param theString
       * @return
       */
      private static int addCifrePari(int totale,String theString)
      {
            int retVal=totale;
            for(int i=1;i<theString.length();){
                 
                        char c=theString.toCharArray()[i];
                        retVal+=getIntFromChar(c);
                      i=i+2;
                 
            }
            return retVal;
      }
      /**
       * Viene fatto il padding a 3 cifre sull'intero e
       * poi è presa l'ultima cifra , quindi si
       * sottrae a 10 questa cifra
       * @param elaborato
       * @return
       */
      private static String getCin(int elaborato)
      {
            DecimalFormat df=new DecimalFormat("000");
            String val=df.format(elaborato);
            char myVal=val.toCharArray()[2];
            int isin=10-getIntFromChar(myVal);
            return String.valueOf(isin);
      }
      /**
       * dato il codice come intero, se è per il calcolo fa il padding degli
       * zeri e poi aggiunge in testa 1829, che è il codice dell'Italia.
       * altrimenti torna il valore col padding
       * @param s
       * @param isForCalcolo
       * @return
       */
    private static String getCodice(int s,boolean isForCalcolo)
    {
      DecimalFormat df=new DecimalFormat("000000000");
      if(isForCalcolo){
            return ITALIAN_CODE+df.format(s);
      }
      else
      {
            return df.format(s);
      }
     
    }
   
    private static String getCodice(String s,boolean isForCalcolo)
    {
            try {
                  int val = Integer.valueOf(s);
                  valida(val);
                  return getCodice(val, isForCalcolo);
            } catch (NumberFormatException nfe) {
            throw new IllegalArgumentException("Attenzione il valore inserito per il conto non è un numero");
            }
    }
   
   
}

Nessun commento:

Posta un commento