Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13

Discussione: Calcolo CRC

  1. #1
    Utente di HTML.it L'avatar di jeky84
    Registrato dal
    Sep 2009
    Messaggi
    43

    Calcolo CRC

    salve a tutti...ho bisogno veramente di un grande aiuto, spero che qualcuno di voi possa aiutarmi

    stò creando un programma per comunicare tramite seriale con java e quando invio i dati,li devo impacchettare in un pacchetto che contiene un preambolo(primo byte) ,la lunghezza del comando+payload(secondo byte), il comando(terzo byte),il payload(dal quarto all'N-1 esimo byte)
    e il CRC di controllo(ultimo byte)
    Il mio problema stà sul CRC, che và calcolato sul comando e sul payload( dal terzo all'N-1 esimo byte cioè)
    Come faccio a calcolare questo benedetto CRC tramite un programmino??
    Il polinomio generatore del CRC è:X^8+X^2+X+1, e i dati che invio sono sotto forma di esadecimali e stringhe!
    Vi prego aiutatemiiii!!!!!
    grazie a tutti e buona giornata

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Calcolo CRC

    Originariamente inviato da jeky84
    Come faccio a calcolare questo benedetto CRC tramite un programmino??
    Il polinomio generatore del CRC è:X^8+X^2+X+1, e i dati che invio sono sotto forma di esadecimali e stringhe!
    Io l'avevo anche scritto un sorgente semplice, di prova che calcola in Java il CRC a 8 bit con quel polinomio .... ma non ce l'ho dietro adesso e dovrei andarlo a cercare.

    Comunque esiste una libreria jFLAC per la gestione di audio in FLAC, formato che prevede proprio un CRC a 8 bit con quel polinomio. Potresti ad esempio dare una "sbirciata" ai sorgenti e in particolare alla classe org.kc7bfi.jflac.util.CRC8.

    EDIT: ho guardato il sorgente di quella classe CRC8, e tra l'altro è semplicissimo perchè usa l'approccio tipico della tabella dei 256 crc già "precalcolata" (è "cablata" nel sorgente).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it L'avatar di jeky84
    Registrato dal
    Sep 2009
    Messaggi
    43
    grazie per la risposta andbin, ho provato a dare uno sguardo all'indirizzo che mi hai segnalato...ma non ci capisco niente anche perchè è in inglese...se ritrovassi quel vecchio programma mi salveresti la vita..cmq per ora grazie mille per l'aiuto

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da jeky84
    ho provato a dare uno sguardo all'indirizzo che mi hai segnalato...ma non ci capisco niente anche perchè è in inglese...
    Beh ok ma a parte l'inglese ..... hai scaricato i sorgenti??? Il sorgente di quel CRC8 è banalissimo. C'è 1 array predefinito di 256 byte con valori "precalcolati" e ci sono dei metodi che dato uno o più byte e il crc "corrente", fanno un "update" e ritornano il nuovo crc aggiornato. E l'update si può ripetere finché non hai finito i dati, ovviamente. Tutto qui.

    E se vuoi il "mio" codice, l'ho trovato. L'avevo postato su un altro forum ma lo posto di seguito. Nota che non ho usato l'approccio "a tabella" ma l'approccio dello shift dei bit. Quindi il mio è meno efficiente!

    codice:
    public class TestCrc8Atm {
        // Polinomio CRC-8 ATM: x^8 + x^2 + x + 1
        public static final byte CRC8ATM_POLY = 0x07;
    
        public static void main(String[] args) {
            // sequenza di test tipica: '123456789', risultato: 0xF4
            byte[] data = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39 };
    
            byte crc = crc8Atm(data);
    
            System.out.format("CRC 8-ATM = %02X%n", crc);
        }
    
        public static byte crc8Atm(byte[] v) {
            byte crc = 0;
    
            for (byte b : v) {
                crc = (byte) (crc ^ b);
    
                for (int i = 0; i < 8; i++) {
                    crc = (byte) (crc << 1 ^ ((crc & 0x80) != 0 ? CRC8ATM_POLY : 0));
                }
            }
    
            return crc;
        }
    }
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it L'avatar di jeky84
    Registrato dal
    Sep 2009
    Messaggi
    43
    grandeeeeeeeeeeeeeeeeee!!!!!grazie grazie grazie grazie grazie!!!!!!
    Stasera me faccio na bevuta alla tua salute!!!!
    ancora grazie mille...mi hai salvato!!!!
    ciaooooooooooooooooooooooooo!!!!

  6. #6
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    18
    Ciao andbin, anche io ho un problema simile...
    Ho dato uno sguardo alla documentazione della Jflac e alla classe che hai suggerito, l'ho scaricata ed ho copiato i file .jar nella cartella di installazione della jdk del java, un po come avevo fatto per installare le librerie della rxtx per le comunicazioni seriali. Dalla documentazione che ho visto sembra facile da utilizzare vi è un semplice costruttore privo di parametri ed il metodo calc che restituisce di botto il crc. Il problema è che non riesco a farlo funzionare, nel senso non mi trova la classe e dunque nn mi fa creare un oggetto di tipo CRC8.
    Sicuramente ho sbagliato ad installarla, come la si deve installare per poterla usare?
    Volevo imparare ad utilizzarla


    Inoltre,
    Prima di aver letto questo post avevo provato a buttar giu una semplice classe per il calcolo del crc inserendo i 256 valori della tabella fornitami, ma quando vado a riempire l array di byte mi da un messaggio di perdita di precisione, cosa significa??

    Ti posto cio che avevo fatto:

    public class Crccalc {


    byte [] Crctab= { 0x00,0x07,0x0E,0x09,0x1C, 0x1B,0x12,0x15,0x38,0x3F,0x36,
    0x31,0x24,0x23,0x2A,0x2D,0x70,0x77,0x7E,0x79,0x6C, 0x6B,
    0x62,0x65,0x48,0x4F,0x46,0x41,0x54,0x53,0x5A,0x5D, 0xE0,
    0xE7 ... Dovrebbero essere 256 Mi da l'errore su perdita di precisione
    };
    public byte getCrc ( byte [] datain, byte datalength, byte initval) {

    byte tableindex=0x00;
    byte crc=initval;
    byte i= 0x00;

    for (i=0x00; i<datalength; i++) {
    tableindex=((byte)(crc^datain[i]));
    crc=Crctab[tableindex];
    }
    return crc;
    }
    }

    Se riuscissi a inserire tutti i 256 elementi della tabella, con una classe siffatta posso ottenere il crc richiamando il metodo getCrc? Se cio puo funzionare come posso inserire i valori della tabella?

    Grazie mille ciao ciao

  7. #7
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    18
    ah dimenticavo, ho provato ad implementare il codice che avevi postato qua sopra ma con scarsi risultati, anche in questo caso andando a passare all'array data i dati da inviare mi dava sempre lo stesso messaggio di perdita di precisione...

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Sampy84
    vi è un semplice costruttore privo di parametri
    Non definisce esplicitamente un costruttore (rimane quello di "default") ma in ogni caso non serve. Quella classe CRC8 non ha "stato" e i metodi invocabili sono solo "statici".

    Originariamente inviato da Sampy84
    Il problema è che non riesco a farlo funzionare, nel senso non mi trova la classe
    Le questioni sono 2: che il jar sia in "classpath" e che tu abbia fatto nel tuo sorgente l'import corretto, perché quella classe è in un package org.kc7bfi.jflac.util.

    Originariamente inviato da Sampy84
    ma quando vado a riempire l array di byte mi da un messaggio di perdita di precisione, cosa significa??
    Se guardi quel sorgente infatti nell'array ci sono tutti cast (byte). Un byte è "signed" e un valore es. 0x9D è una costante "intera" con valore 157 quindi fuori dal range -128..+127 dei byte.

    Originariamente inviato da Sampy84
    Se riuscissi a inserire tutti i 256 elementi della tabella
    Copiare pedestremente l'array da quel sorgente??
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Utente di HTML.it L'avatar di jeky84
    Registrato dal
    Sep 2009
    Messaggi
    43
    sampy quella classe non l'ho usata nemmeno io e ok...ma quella che hai postato tu ha un errore sulla tabella...nel senso:
    per forza ti dà pssible loss of precision...tu vuoi mettere in un array di byte (che vanno da -128 a 127) valori che valgono anche 200...non ci entrano...prova a usare una strategia per evadere la cosa
    per esempio...potresti creare un metodo nel quale vai a scrivere quei valori in un array di interi, e poi vai a prendere di quei valori solo la parte utile(cioè quella piena)
    Nel senso...il numero più grande che puoi trovare è 0xFF(cioè 255)...quindi se lo metti in un intero e poi fai un and logico con qualcosa che ti elimina la parte "vuota"dell'intero ottieni il valore che ti occorre nel formato che ti serve...
    ES:
    a=255=00000000000000000000000011111111(in un intero)....and logico con un valore numerico che ti restituisce 1 se il bit di a=1, 0 altrimenti
    Qual'è questo valore numerico??? facile proprio 255(cioè 11111111)!!!!!
    ah a riguardo del fatto che mettendolo in un intero sprechi più memoria che in un byte non ti preoccupare, tanto per questioni prestazionali un byte in realtà non occupa 1 byte solo ma 4 byte come un int...quindi!!!

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    18
    Ciao, credo di aver trovato una soluzione per poter salvare i valori della tabella in un array di byte ma vorrei sapere se è correto.
    inizialmente creo un array di short[] di dimensione pari a 256 e vi memorizzo i valori, poi utilizzando il suo metodo byteValue(), che restituisce un byte, vado a riempire un array di byte.
    Se questo è corretto poi ho utilizzato la mia classe:


    package Codifica;


    public class Crccalc {

    Short [] tab={0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15,0x38, 0x3F,0x36,0x31,0x24,
    0x23,0x2A,0x2D,0x70,0x77,0x7E,0x79,0x6C,0x6B,0x62, 0x65,0x48,0x4F,
    0x46,0x41,0x54,0x53,0x5A,0x5D,0xE0,0xE7,0xEE,0xE9, 0xFC,0xFB,0xF2,
    0xF5,0xD8,0xDF,0xD6,0xD1,0xC4,0xC3,0xCA,0xCD,0x90, 0x97,0x9E,0x99,
    0x8C,0x8B,0x82,0x85,0xA8,0xAF,0xA6,0xA1,0xB4,0xB3, 0xBA,0xBD,0xC7,
    0xC0,0xC9,0xCE,0xDB,0xDC,0xD5,0xD2,0xFF,0xF8,0xF1, 0xF6,0xE3,0xE4,
    0xED,0xEA,0xB7,0xB0,0xB9,0xBE,0xAB,0xAC,0xA5,0xA2, 0x8F,0x88,0x81,
    0x86,0x93,0x94,0x9D,0x9A,0x27,0x20,0x29,0x2E,0x3B, 0x3C,0x35,0x32,
    0x1F,0x18,0x11,0x16,0x03,0x04,0x0D,0x0A,0x57,0x50, 0x59,0x5E,0x4B,
    0x4C,0x45,0x42,0x6F,0x68,0x61,0x66,0x73,0x74,0x7D, 0x7A,0x89,0x8E,
    0x87,0x80,0x95,0x92,0x9B,0x9C,0xB1,0xB6,0xBF,0xB8, 0xAD,0xAA,0xA3,
    0xA4,0xF9,0xFE,0xF7,0xF0,0xE5,0xE2,0xEB,0xEC,0xC1, 0xC6,0xCF,0xC8,
    0xDD,0xDA,0xD3,0xD4,0x69,0x6E,0x67,0x60,0x75,0x72, 0x7B,0x7C,0x51,
    0x56,0x5F,0x58,0x4D,0x4A,0x43,0x44,0x19,0x1E,0x17, 0x10,0x05,0x02,
    0x0B,0x0C,0x21,0x26,0x2F,0x28,0x3D,0x3A,0x33,0x34, 0x4E,0x49,0x40,
    0x47,0x52,0x55,0x5C,0x5B,0x76,0x71,0x78,0x7F,0x6A, 0x6D,0x64,0x63,
    0x3E,0x39,0x30,0x37,0x22,0x25,0x2C,0x2B,0x06,0x01, 0x08,0x0F,0x1A,
    0x1D,0x14,0x13,0xAE,0xA9,0xA0,0xA7,0xB2,0xB5,0xBC, 0xBB,0x96,0x91,
    0x98,0x9F,0x8A,0x8D,0x84,0x83,0xDE,0xD9,0xD0,0xD7, 0xC2,0xC5,0xCC,
    0xCB,0xE6,0xE1,0xE8,0xEF,0xFA,0xFD,0xF4,0xF3};


    public byte getCrc ( byte [] datain, byte datalength) {

    int n=0;
    byte [] Crctab=new byte[256];

    for (n=0; n<tab.length; n++){
    Crctab[n]= tab[n].byteValue();
    }


    byte tableindex=0x00;

    byte crc=0x00;
    //byte i= 0x00;
    int i=0;
    byte leng=(byte)11;

    for (i=0x00; i<leng; i++) {

    tableindex=((byte)(crc^datain[i]));


    // Aggiornamento del crc
    crc=Crctab[tableindex]; // vado a prendere il valore della tabella nella posizione tableindex
    }

    return crc;
    }
    }


    Il ciclo for deve ciclare 11 volte perche i byte di dati sono 11, e ogni volta deve fare lo Xor tra il valore corrente del crc e l'iesimo byte di dati.
    Il crc vale esattamente come il tableindex-esimo elemento dell'array e questo viene aggiornato 11 volte. poi alla fine viene restituito.
    Però ho un problema che nn riesco a risolvere, tableindex mi indica in poche parole quale elemento della tabella mi dovra andare a sostituire il crc ma mi da continuamente quest'eccezzione ArrayIndexOutOfBounds !!!
    Ho provato a convertire il valore tableindex, perche se questo è per caso > di 127 ho problema di visualizzazione, quindi se ad esempio l'uscita del for mi da come risusltato che il crc deve essere uguale all 195-esimo elemento della tabella, come faccio a impostargli tale valore??? :master:
    Perche se ad esempio gli imposto crc=Crctab[0x22] non mi da problemi...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.