+ Répondre à la discussion
Affichage des résultats 1 à 7 sur 7
  1. #1
    Futur Membre du Club
    Inscrit en
    avril 2006
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : avril 2006
    Messages : 36
    Points : 16
    Points
    16

    Par défaut Calcul CRC8 ou CheckSum port série

    Bonjour à tous,

    Je dois pouvoir lire et écrire des infos sur des cartes à puce de type Siemens SLE 4432/4442 répondant aux normes ISO 7816 à partir d'un lecteur série répondant aux mêmes normes.

    Je n'ai aucune doc concernant le lecteur (le cd qui va avec est gentiment retiré d'office par le fournisseur et pas moyen de contacter le constructeur en Chine).

    Voici mon problème :

    lors de l'envois/réception de trames vers le/du lecteur, le dernier octet correspond à un cheksum ou un crc8 que je n'arrive pas à calculer.

    J'ai essayé les algorithmes de modulos 256, crc8 etc sans trouver.

    J'espère qu'en donnant des exemples de trames, quelqu'un pourra m'aider à comprendre quel algoritme est utilisé pour calculer le dernier octet envoyé ou reçu (a mon avis, cela doit correspondre à des normes d'autres lecteurs plus connus).

    voici des exemples de trames envoyées au lecteur:

    en orange : le nombre d'octets envoyés après (sans l'octet final)
    en bleu : le nombre d'octets de données attendus dans la réponse
    en rouge : l'octet de vérification (cheksum ou autre)

    AA B0 00 07 80 00 00 00 00 00 0A 97

    Si dans cette trame je change la valeur bleue et rouge de la manière suivante (-2), celà fonctionne et je reçois bien 2 caractères en moins dans la réponse.

    AA B0 00 07 80 00 00 00 00 00 08 95

    autres exemple de trames qui fonctionnent :
    AA 61 00 07 77 00 00 00 20 00 10 8B

    AA 61 00 07 77 00 00 00 30 00 30 BB

    AA 61 00 07 77 00 00 00 2E 00 01 94

    par contre, une mauvaise trame envoyée au lecteur me renvoye comme réponse une trame dont le dernier octet peut-être calculer sur base d'un checksum modulo 256:

    55 8A 00 00 DF
    (55+8A) mod 256 = DF un hasard ?

    J'espère que quelqu'un pourra m'éclairer sur le sujet parce que je ne sait plus par ou chercher.

    Merci d'avance.

  2. #2
    Rédacteur/Modérateur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    décembre 2006
    Messages
    9 960
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : décembre 2006
    Messages : 9 960
    Points : 15 759
    Points
    15 759

    Par défaut

    Connaissant Siemens, c'est surement du BCC: il suffit de faire un XOR de tous les octets de la trame. Si le résultat est zero, c'est qu'il n'y a pas d'erreur dans la trame

    => le dernier octet est égal au XOR de tous les précédents.
    AA xor B0 xor 00 xor 07 xor 80 xor 00 xor 00 xor 00 xor 00 xor 00 xor 0A = 97
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  3. #3
    Futur Membre du Club
    Inscrit en
    avril 2006
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : avril 2006
    Messages : 36
    Points : 16
    Points
    16

    Par défaut

    Citation Envoyé par pseudocode Voir le message
    Connaissant Siemens, c'est surement du BCC: il suffit de faire un XOR de tous les octets de la trame. Si le résultat est zero, c'est qu'il n'y a pas d'erreur dans la trame

    => le dernier octet est égal au XOR de tous les précédents.
    AA xor B0 xor 00 xor 07 xor 80 xor 00 xor 00 xor 00 xor 00 xor 00 xor 0A = 97
    Je te remercie beaucoup pour ta réponse...

    En fait j'ai trouvé à peu près en même temps et effectivement c'est un LRC donc le dernier octet est un XOR des précédents.

    Le problème c'est que avec la fatigue (je suis têtu et je suis capable d'y passer une 20taine d'heures d'affilées) j'ai fais une bétise.

    J'ai testé plusieurs algoritmes sur base d'une mauvaise chaine.
    Voulant effacé le dernier octet envoyé ou reçu pour le recalculer, j'ai effacé l'avant dernier octet de la chaine..

    Donc pour calculer le dernier octet de

    AA B0 00 07 80 00 00 00 00 00 0A = 97

    je le calculais sur la chaine

    AA B0 00 07 80 00 00 00 00 00 97 = 0A

    C'est ce qui m'a mis la puce à l'oreille.

    Encore merci.

    Maintenant, il me reste à analyser les données contenues dans les trames reçues ou envoyées, mais ca c'est une autre histoire et je ne sais pas si je peux abuser.

  4. #4
    Futur Membre du Club
    Inscrit en
    avril 2006
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : avril 2006
    Messages : 36
    Points : 16
    Points
    16

    Par défaut

    Je n'ai pas fermé le sujet parce que je me doutais bien que j'aurais d'autres problèmes.

    Je ne sais pas si je peux continuer ici ou si je dois en créer un nouveau.

    Comme cela reste dans le même style, je me dis qu'on peut continuer ici, surtout que 'pseudocode' à l'air de s'y connaitre au niveau des puces Siemens.

    Bon voilà...

    Suite à la commande 'AA 61 00 07 77 00 00 00 30 00 30 BB' envoyée au lecteur (avec la carte insérée), je reçois la réponse suivante :

    '55 00 00 30 2D D4 7C FF 6E DA 46 C9 52 DF 5C 4B 57 D5 02 D0 5D CB 58 D6 FC 7A 5E DC 59 D7 54 B6 57 DF CA 71 7B FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 29'

    En rouge: la partie de trame provenant du lecteur (OK)
    En orange: la partie de trame correspondant à ce qui a été lu sur la carte.

    On peut oublier la partie de la trame envoyée par le lecteur de carte ainsi que la partie de la trame comportant des FF à la fin.

    Il reste :
    2D D4 7C FF 6E DA 46 C9 52 DF 5C 4B 57 D5 02 D0 5D CB 58 D6 FC 7A 5E DC 59 D7 54 B6 57 DF CA 71 7B

    Les valeurs en rouge sont inchangables (2D du début de trame et 7B en fin)

    L'avant dernière valeur (71) ressemble à un LRC parce que si on l'augmente de 1 ou de 2 en même temps q'une autre valeur dans la trame, c'est OK, sauf que c'est pas un LRC, mais alors c'est quoi ? .

    Je ne vois pas à quoi correspondent les valeurs 'D4 7C' en début de trame.

    Je connais les valeurs affichées par les autres champs, mais je n'arrive pas à trouver comment calculer ces valeurs.

    Voici le détail :
    FF 6E DA 46 C9 = 0510013321 (string)
    52 = 01 (Integer)
    DF 5C = 0000 (Integer)
    4B 57 D5 = 91,9 la façon d'afficher ce champ est modifiée par la valeur CA en fin de trame. (Float)
    02 D0 5D = 000050 (Integer)
    CB 58 D6 = 000010 (Integer)
    FC 7A 5E = 009999 (Integer)
    DC 59 D7 = 000000 (Integer)
    54 B6 57 = 086400 (Integer)
    DF=10

    1° les valeurs enregistrées sur la carte ne semblent pas tenir compte du type (string, integer ou float); 0510013321 en string à l'air d'être traité de la même façon que 000050 qui est un Integer.

    2° Je ne trouve pas comment traduire ce qui est lu sur la carte et la valeur à obtenir. (ex CB 58 D6=000010 et DC 59 D7=000000).

    Si quelqu'un à une idée, pour me mettre sur la voie, ce serais vraiment tres sympa...

    Merci

  5. #5
    Membre du Club
    Homme Profil pro
    informatique industrielle & domotique - Delphi
    Inscrit en
    janvier 2006
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : informatique industrielle & domotique - Delphi

    Informations forums :
    Inscription : janvier 2006
    Messages : 94
    Points : 58
    Points
    58

    Par défaut un exemple de crc8 que je cherche a transposer en pascal

    Bonjour.
    J'ai un problème apparenté a celui-ci mais peut-être que cela peut t'aider si tu maîtrise le C


    J'ai un exemple de crc8 en C que je ne sais pas transposer en pascal (delphi)

    Voici ce code :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    2.3 CRC8 calculation
    The polynomial G(x) = x8 + x2 + x1 + x0 is used to generate the CRC8 table, needed
    for the CRC8 calculation. Following C code illustrates how the CRC8 value is calculated:
    Implementation:
    uint8 u8CRC8Table[256] = {
    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
    };
    #define proccrc8(u8CRC, u8Data) (u8CRC8Table[u8CRC ^ u8Data])
    Example:
    u8CRC = 0;
    for (i = 0 ; i < u16DataSize ; i++)
    u8CRC = proccrc8(u8CRC, u8Data[i]);
    printf("CRC8 = %02X\n", u8CRC);

  6. #6
    Expert Confirmé Sénior Avatar de Graffito
    Inscrit en
    janvier 2006
    Messages
    5 842
    Détails du profil
    Informations forums :
    Inscription : janvier 2006
    Messages : 5 842
    Points : 7 555
    Points
    7 555

    Par défaut

    Je ne pratique plus Dephi depuis 5 ans, mais ça devrait donner ceci :
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Const u8CRC8Table : Array[0..255] of Byte = (
     $00, $07, $0e, $09, $1c, ...
    
    var 
      u8Crc  : Byte ; 
      Buffer : array[0..4095] of Byte ; // maxBufferSize = 4096
      BufferSize : integer ;
    begin
    Buffer= ...
    BufferSize = ...
    u8CRC := 0; 
    for i := 0 to BufferSize do u8CRC := u8CRC8Table[u8CRC xor Buffer[i]];
    ...
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  7. #7
    Membre du Club
    Homme Profil pro
    informatique industrielle & domotique - Delphi
    Inscrit en
    janvier 2006
    Messages
    94
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : informatique industrielle & domotique - Delphi

    Informations forums :
    Inscription : janvier 2006
    Messages : 94
    Points : 58
    Points
    58

    Par défaut Bravo.. c'est vérifié.

    Bien vu.
    Routine testée en réel .. ça marche

    Grand merci.

+ Répondre à la discussion
Cette discussion est résolue.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •