Avatar billede ghorfraq Nybegynder
02. juli 2008 - 14:18 Der er 10 kommentarer og
1 løsning

checksum algoritme

Hej

Jeg har en streng (char* str) indeholdende hex værdier (Det er en s19 record fra en .s19 fil, hvis det sku interessere nogle :-) ).
Hver hexværdi udgøres af 2 cifre i strengen, dvs. str[0] og str[1]
udgør altså det hexadecimale tal 21

strengen: 1455A2903339385C75303339355C75303339392058

De sidste 2 cifre i strengen er strengens checksum. checksummen beregnes i teorien på følgende måde (1 komplement checksum):

Alle hexværdierne lægges sammen.
summen skal truncates med ( and 0x00FF ) for at sikre man kun har 2 cifre.
Sidst findes komplementet (værdien inverteres)

Jeg har selv udarbejdet følgende kode, som ikke virker:
Når imine summerede hexværdier bliver ANDED med 0x00FF får jeg resultatet 1, hvilket jeg antager er forkert :-) og min beregnede checksum bliver -2 hehe. Det er vigtigt at det er de hexadecimale værdier der lægges sammen. Som min kode er lægger jeg den decimale værdi sammen (base 10). Men jeg er ikke klar over hvordan jeg ellers kan håndtere hexværdier fra en streng.
________________________________________________________________________________________
//Her udhentes hexværdierne og hver værdi kopieres til en integer.
kodeuddrag:

  while( !(dataIndex >= endIndex) )
  { 
  checkSumStr[0] = srec[dataIndex];
  checkSumStr[1] = srec[ (dataIndex + 1) ];

  sscanf(checkSumStr, "%x", &temp);    //Copy the hex value to an int
  printf("\nCheckSum integer type: %d", temp);
  printf("\nCheckSum from string: %s\n", checkSumStr);
           
  calculatedChecksum += temp;
  printf("CALCULATING CheckSum integer type: %d\n", calculatedChecksum);

  dataIndex = dataIndex+2;           
  }
 
  calculatedChecksum = calculatedChecksum && 0x00FF; //truncating to 2 digits.
  printf("\n\ANDED CheckSum integer type: %d", calculatedChecksum);
       
  calculatedChecksum = ~calculatedChecksum; //finding 1'st complement (inverted)       
  printf("\n\nCALCULATED CheckSum integer type: %d", calculatedChecksum);
________________________________________________________________________________________
Avatar billede pidgeot Nybegynder
02. juli 2008 - 14:21 #1
Du skal bruge bitvis AND (&), ikke boolsk (&&).
Avatar billede ghorfraq Nybegynder
02. juli 2008 - 14:25 #2
bør lige tilføje at checksum resultatet på -2 jo er forkert, da man kan se på de 2 diste cifre i strengen (som ikke medregnes i algoritmen) at checksummen skal være 81.
Avatar billede ghorfraq Nybegynder
02. juli 2008 - 14:26 #3
hvordan gør jeg det pidgeot?
Avatar billede pidgeot Nybegynder
02. juli 2008 - 14:33 #4
Som jeg hintede til, skal du bruge & i stedet for && - dvs. du retter:

calculatedChecksum = calculatedChecksum && 0x00FF;

til:

calculatedChecksum = calculatedChecksum & 0x00FF;

&& betragter nemlig begge sider som boolske variable - dvs. den checker på om de to ting der står på hver side begge er forskellige fra FALSE (0) (i hvilket tilfælde den returnerer TRUE, eller 1). & derimod laver en AND på de individuelle bits - så hver bit i resultatet bliver sat til 1 hvis den same bit var sat til 1 i begge de to inputs. Når det ene input er en konstant, fungerer den som en bitmaske - dvs. den fjerner alle de bits fra det andet input der ikke er repræsenteret i din maske.

Lige for en god ordens skyld, så er det ikke sikkert det er det eneste der er galt med din algoritme - jeg lagde bare mærke til netop den del. :)
Avatar billede ghorfraq Nybegynder
02. juli 2008 - 14:35 #5
hehe, regnede det godt ud da jeg læste det anden gang :-). ER vist ved at være træt... Må hellere hente mere kaffe. er lige ved at teste med bitwise and. vender tilbage om lidt
Avatar billede ghorfraq Nybegynder
02. juli 2008 - 14:39 #6
med bitwise AND bliver resultatet -103. Så jeg gør det ikke korrekt.
prøver lige at bruge XOR istedet for AND og invertering.
Avatar billede ghorfraq Nybegynder
02. juli 2008 - 14:43 #7
intet held med XOR. Synes bare jeg ku huske jeg benyttede det i en checksums algoritme i tidernes morgen.
Avatar billede ghorfraq Nybegynder
02. juli 2008 - 14:45 #8
Checksums-resultatet bør selvfølgelig være 58 og ik 81 som tidligere skrevet.
Avatar billede arne_v Ekspert
03. juli 2008 - 04:52 #9
#include <stdio.h>
#include <string.h>

int val(char *s, int ix)
{
    int res;
    sscanf(s + ix, "%02x", &res);
    return res;
}

int chksum(char *s)
{
    int i, res;
    res = 0;
    for(i = 0; i < strlen(s) - 2; i += 2)
    {
        res += val(s, i);
    }
    res = ~res;
    res &= 0xFF;
    return res;
}

int valid(char *s)
{
    return val(s, strlen(s) - 2) == chksum(s);
}

int main()
{
    char *s = "1455A2903339385C75303339355C75303339392058";
    printf("chksum = %02X\n", chksum(s));
    printf("valid = %s\n", valid(s) ? "true" : "false");
    return 0;
}
Avatar billede ghorfraq Nybegynder
03. juli 2008 - 09:19 #10
Tak for eksemplet arne_v. Det virker perfekt. Har lige lavet nogle modifikationer så det passer ind i mit program.

Smid et svar og du får pointene.

Og du får også tak for dine indlæg pidgeot. Dog må det være arne der løber med pointene, da han fik algoritmen til at fungere.
Avatar billede arne_v Ekspert
03. juli 2008 - 13:25 #11
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester