amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Checksumme berechnen? [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

16.03.2004, 19:49 Uhr

Palgucker
Posts: 1342
Nutzer
Hallo

Wie berechnet man eigendlich die Checksumme für einen Festplattenblock oder das Rom? Ich habe mir zwar schonmal in Amos solch ein Programm geschrieben, das aber auch nicht so ganz genau hinhaut. D.h., das Programm berechnet eine Checksumme, die der richtigen zwar sehr nahe kommt, aber meistens etwas daneben liegt. Im Netz habe ich bis jetzt auch nicht das passende gefunden. Hoffe, das es hier klappt.

mfg Palgucker


[ - Antworten - Zitieren - Direktlink - ]

17.03.2004, 09:10 Uhr

thomas
Posts: 7717
Nutzer
code:
/* checksumme an stelle 2 (offset 4) */

ULONG checksum (ULONG *block, long size)
{
long i;
ULONG sum;

size <<= 2; /* size in bytes -> size in longs */

block[1] = 0;  /* alte checksumme auf null setzen */

sum = 0;
for (i = 0; i < size; i++)
   sum -= block[i];

block[1] = sum; /* neue checksumme eintragen */

return (sum);
}


Im Prinzip müßte es so gehen. Allerdings habe ich das alles aus dem Gedächtnis geschrieben, könnten also Fehler drin sein. Ich kann heute abend zuhause nochmal nachsehen, wie es richtig ist.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: home.t-online.de/home/thomas-rapp/

[ Dieser Beitrag wurde von thomas am 17.03.2004 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

17.03.2004, 12:13 Uhr

Solar
Posts: 3680
Nutzer
Öhm...

Ich habe nie mit der AmigaAPI gearbeitet, aber... ist das allen Ernstes das, was das Amiga FFS als "Checksumme" bezeichnet? :shock2:

[ - Antworten - Zitieren - Direktlink - ]

17.03.2004, 15:52 Uhr

thomas
Posts: 7717
Nutzer

Was hat das mit API zu tun und was verstehst du unter einer Checksumme ?

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: home.t-online.de/home/thomas-rapp/

[ - Antworten - Zitieren - Direktlink - ]

17.03.2004, 16:44 Uhr

Mad_Dog
Posts: 1944
Nutzer
Zitat:
Original von thomas:

Was hat das mit API zu tun und was verstehst du unter einer Checksumme ?


Eine Prüfsumme dient normalerweise dazu, um festzustellen, ob ein oder mehrere Bits zufälligerweise (d.h. durch einen Übertragungsfehler/Rauschen) umgekippt sind. Das Verfahren habe ich leider schon wieder aus meiner geistigen Warteschlange verdrängt. ;)

--

http://www.norman-interactive.com

[ Dieser Beitrag wurde von Mad_Dog am 17.03.2004 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

17.03.2004, 17:08 Uhr

Palgucker
Posts: 1342
Nutzer
@ Thomas

Danke für die Info. Aber mit C eiere ich noch ganz schön 'rum. Darum nochmal so, wie ich es verstanden habe.

Also ich lade einen Testblock in den Speicher, setze die Checksumme auf Null und lese langwordweise die Daten als unsigned int. Diese Daten substrahiere ich einfach zu einer Summe (erstaunlich, das man auch mit Substraktion Summen erhält ;) ). Zum Schluss sollte dann die Checksumme dabei rauskommen. Nur bei mir klappt das nicht so richtig.

mfg Palgucker

[ - Antworten - Zitieren - Direktlink - ]

17.03.2004, 17:18 Uhr

Mad_Dog
Posts: 1944
Nutzer
Also der Code von thomas rechnet zwar eine Summe aus, aber das ist ganz bestimmt keine Prüfsumme.

Ich habe hier mal in meinem Skript zur Technischen Informatik nachgeschlagen. Ich zitiere mal daraus:


Fehlererkennende und -korregierende Codes werden u.a. bei der Datenübertragung und bei Speichern verwendet und dienen dazu, Fehler die bei der Übertragung (oder Speicherung) aufgetreten sind, zu erkennen bzw. zu korregieren. Dazu erweitert der Sender die Datenwörter um zusätzliche, redundante Prüfbits.

Als Fehler bezeichnet man in diesem Zusammenhang das "unerwünschte" Flippen (z.B. durch Signalstörungen etx. bedingt) eines oder mehrerer Bits (1->0 oder 0->1) im übertragenden Codewort, was zu einem neuen nicht mehr korrekten Codewort führt.


Ich hab das vollständige Skript (knapp 400 Seiten) noch als pdf (ca. 4MB) da. Wenn Du willst, kann ich's Dir per email schicken.
--

http://www.norman-interactive.com

[ - Antworten - Zitieren - Direktlink - ]

17.03.2004, 18:59 Uhr

thomas
Posts: 7717
Nutzer

Ich weiß, was eine Prüfsumme ist. Und mit ein bißchen Phantasie ist das o.g. auch eine Prüfsumme. Die offizielle Beschreibung des Feldes ist sinngemäß "ein Langwort, das die Summe aller Langwörter in dem Block zu 0 werden läßt". Nach deiner Definition ist die Prüfsumme (also ein *zusätzliches* Daten-Wort) immer 0, während das zweite Wort so angepaßt wird, daß das immer hinkommt. Lapidar kann man sagen, daß das zweite Wort die Prüfsumme ist, ohne die Definition wesentlich zu verletzen.

@Palgucker, dem Prozessor ist es ziemlich egal, ob er addiert oder subtrahiert, da die Über- bzw. Unterläufe ignoriert werden. Du kannst auch alle Worte addieren und am Ende das Ergebnis negieren.

Und wenn du die alte Prüfsumme nicht überschreiben möchtest, kannst du es auch so machen:

code:
ULONG checksum (ULONG *block, long size)
{
long i;
ULONG sum;

size <<= 2; /* size in bytes -> size in longs */

sum = block[0];
for (i = 2; i < size; i++)
   sum += block[i];

return (sum);
}

void main (void)
{
block[2] = -checksum(block,512);
}


Dabei bekäme unsere "Prüfsumme" auch wieder den Charakter eines zusätzlichen Datenwortes.

Gruß Thomas
--
Email: thomas-rapp@web.de
Home: home.t-online.de/home/thomas-rapp/

[ - Antworten - Zitieren - Direktlink - ]

17.03.2004, 19:08 Uhr

Palgucker
Posts: 1342
Nutzer
@ Mad_Doc

quote:
Also der Code von thomas rechnet zwar eine Summe aus, aber das ist ganz bestimmt keine Prüfsumme.

Aber Thomas weiss, was ich meine. Und diese Summe ist die, die den berühmten Checksumerror hervorruft - also nennen wir sie ruhig Checksumme.

Ich habe hier mal in meinem Skript zur Technischen Informatik nachgeschlagen. Ich zitiere mal daraus:
Fehlererkennende und -korregierende Codes werden u.a. bei der Datenübertragung und bei Speichern verwendet und dienen dazu, Fehler die bei der Übertragung (oder Speicherung) aufgetreten sind, zu erkennen bzw. zu korregieren. Dazu erweitert der Sender die Datenwörter um zusätzliche, redundante Prüfbits.


Genau das macht diese Summe bis auf das korregieren ja auch. Diese Summe ist zumindest auf dem Amiga recht verbreitet. zu finden in jeden RDB,OFS,FFS und auch das erste Langword des Amigarom's ist wohl aus dieser Rechnung entstanden. Das es noch einen ganzen Sack voll anderer Methoden gibt, ist mir schon klar.

mfg Palgucker

[ - Antworten - Zitieren - Direktlink - ]

18.03.2004, 00:53 Uhr

Mad_Dog
Posts: 1944
Nutzer
Zitat:
Original von Palgucker:

Genau das macht diese Summe bis auf das korregieren ja auch. Diese Summe ist zumindest auf dem Amiga recht verbreitet. zu finden in jeden RDB,OFS,FFS und auch das erste Langword des Amigarom's ist wohl aus dieser Rechnung entstanden. Das es noch einen ganzen Sack voll anderer Methoden gibt, ist mir schon klar.


Ehrlich gesagt habe ich mir noch nicht genau angeschaut, wie das bei den Amiga-Filesystemen gelöst ist. Aber eine Prüfsumme würde ohne Fehlerkorrektur kaum Sinn machen. Anhand der Prüfsumme kann man ja erkennen, ob und welche Bits sich geändert haben und sie dann einfach wieder "umdrehen" (0->1 , 1->0).

Ich kenn das so, daß der Empfänger die Prüfsumme anhand der Datenbits neu berechnet und anschließend überprüft, ob diese neu berechnete Prüfsumme mit der gesendeten Prüfsumme übereinstimmt.

Also ein n-Bit Wort X=(x0,x1,...,xn) wird ergänzt zu einem (n+1)-Bit Wort X* = (x0,x1,...,xn-1,c0). c0 ist das Paritätsbit.

Dann gilt:

Gerade Parität: c0 := x0 xor x1 xor ... xor xn-1
Ungerade Parität: not c0 := x0 xor x1 xor ... xor xn-1

Der Empfänger berechnet dann, wie bereits oben erwähnt seinerseits die Parität und überprüft, ob sie mit der gesendeten Parität übereinstimmt.

c0* := x0' xor x1' xor ... xor x'n-1 (gerade Parität)

Die Information ist fehlerhaft, wenn gilt:

c0* ungelich c'0

Wenn man mehrfache Fehler erkennen will, braucht man 2^c >= n+c+1 Prüfbits.

Also z.B. für n=16 z.B. c >= 5

Bei n=8 Datenbits sieht das so aus:

X=(d0,...d7,c0,...c3).

c0 bis c3 sind hier die Prüfbits.

Dann rechnet man:

c0 = d0 + d1 + d2 + d3 + d4 + d5 + d6
c1 = d0 + d2 + d4 + d7
c2 = d1 + d2 +d5 +d7
c3 = d3 + d4 + d5 +d6

Der Empfänger errrechnet dann den sogenannten Fehlervektor:

E:= (c'0 xor c0', ... c3' cor c3*)

Wenn E der Nullvektor ist, sind keine Fehler aufgetreten.

Welches Bit gekippt ist kann man auch leicht erkennen:

E=(0,1,0,0) <-> c1' fehlerhaft
E=(1,1,0,0) <-> d0' fehlerhaft
E=(1,0,1,0) <-> d1' fehlerhaft
E=(1,1,1,0) <-> d2' fehlerhaft

So... das war nun ein wenig Theorie. :)

Kann auch sein, daß thomas genau das gemeint hat, sich aber etwas unglücklich ausgedrückt hat.

--

http://www.norman-interactive.com

[ - Antworten - Zitieren - Direktlink - ]

18.03.2004, 11:52 Uhr

thomas
Posts: 7717
Nutzer

Zitat:
Aber eine Prüfsumme würde ohne Fehlerkorrektur kaum Sinn machen.

Das stimmt nicht. Die Prüfsumme wird vom Absender berechnet und mit übertragen, dann vom Empfänger nochmal berechnet und mit der gesendeten verglichen.

Zitat:
Ich kenn das so, daß der Empfänger die Prüfsumme anhand der Datenbits neu berechnet und anschließend überprüft, ob diese neu berechnete Prüfsumme mit der gesendeten Prüfsumme übereinstimmt.

Sag ich ja. Damit kannst du erstmal nur sagen, ob die Daten korrekt sind, oder nicht. Ob man mit Hilfe der Prüfsumme auch eine Fehlerkorrektur machen kann, kommt auf die Anzahl und Verteilung der Prüfbits an und ob man das überhaupt möchte.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: home.t-online.de/home/thomas-rapp/

[ - Antworten - Zitieren - Direktlink - ]

18.03.2004, 13:16 Uhr

platon42
Posts: 400
[Ex-Mitglied]
Zitat:
Aber eine Prüfsumme würde ohne Fehlerkorrektur kaum Sinn machen.

Eine Pruefsumme ist genau das, ein Wert, mit dem sich Aenderungen mit hoher Wahrscheinlichkeit verifizieren lassen. Verschiedene Pruefsummenverfahren haben verschiedene eigenschaften. Man wuenscht sich natuerlich dabei, dass man moeglichst viele Bitfehler erkennt und das nicht z.B. zwei Bitfehler an verschiedenen Stellen die Pruefsumme wieder korrekt erscheinen lassen. Das ist bei der vom AmigaOS verwendeten Pruefsumme natuerlich nicht der Fall. Zwei mal Bitkippen an der selben Stelle kann dazu fuehren, dass der Fehler nicht erkannt wird. Um soetwas zu vermeiden, verwendet man z.B. Verfahren, die eine hohe Diversitaet haben, sprich, bei dem ein Bit im Durchschnitt ca. 50% der Bits der Checksumme kippen laesst. Beispiel hierfuer sind CRCs (CRC16, CRC32), die mit Polynomdivision auf dem zyklischen Koerper Z_2 arbeiten.

Fehlererkennung hat per se nicht umbedingt etwas mit Fehlerkorrektur zu tun. Ich verweise hier mal auf die Shannon'sche Informationstheorie. Wenn man einen Fehler erkannt hat, z.B. ueber eine CRC16 ueber einen 512 Byte Block, dann heisst es nicht, dass man bestimmen kann, /wo/ der Fehler aufgetreten ist. Dazu reichen die 16 Bits fuer die 4096 Bits nicht aus. Es gibt aber Verfahren, bei denen man mit relativ wenigen extra-Bits pro Informationsbit auskommt (z.B. etwa 10% bei Daten-CDs). Verweis auf Reed-Solomon und Galoisfelder. Allerdings sind diese Verfahren fuer die Fehlerkorrektur *sehr* CPU lastig.

Habe gerade einen Link gefunden, der ganz interessant scheint, fuer jeden, der sich damit naeher beschaeftigen will.

http://www.eccpage.com/
--
--
Best Regards

Chris Hodges

[ - Antworten - Zitieren - Direktlink - ]

18.03.2004, 14:38 Uhr

Solar
Posts: 3680
Nutzer
@ thomas: Ich hätte tatsächlich eher mit so etwas wie einer CRC-Summe gerechnet, weil zuverlässiger - daher mein Entsetzen. So ist's natürlich schneller, aber...

OK, jetzt mal genug der Technischen Informatik und zurück zu Palgucker's Problem.

Wenn Du alle Langwörter des Blocks (inklusive der Checksumme) aufaddierst und dabei Überläufe ignorierst, muß dabei am Ende Null rauskommen, sonst ist der Block Murks.

Aus dem ADF FAQ:

Zitat:
code:
#define Short(p) ((p)[0]<<8 | (p)[1])
#define Long(p) (Short(p)<<16 | Short(p+2))

unsigned long newsum;
unsigned char buf[BSIZE];	/* contains rootblock */
int i;

memset(buf+20,0,4);		/* clear old checksum */
newsum=0L;
for(i=0; i < ( BSIZE/4 ); i++)
	newsum+=Long(buf+i*4);
newsum=-newsum;			/* negation */

This checksum algorithm works for most block types except for Bootblock.

[ Dieser Beitrag wurde von Solar am 18.03.2004 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

18.03.2004, 16:00 Uhr

Mad_Dog
Posts: 1944
Nutzer
Zitat:
Original von platon42:
Zitat:
Aber eine Prüfsumme würde ohne Fehlerkorrektur kaum Sinn machen.

Fehlererkennung hat per se nicht umbedingt etwas mit Fehlerkorrektur zu tun. Ich verweise hier mal auf die Shannon'sche Informationstheorie.


Ja, richtig. Je nach Anwendung kann man auch "nur" überprüfen, ob die Daten korrekt waren oder nicht. Ich hab jetzt ehrlich gesagt keine Lust, mir anzuschauen, wie das bei den Amiga Filesystemen gelöst ist. ;)


--

http://www.norman-interactive.com

[ - Antworten - Zitieren - Direktlink - ]

19.03.2004, 12:38 Uhr

Palgucker
Posts: 1342
Nutzer
Nun muss ich mich auch noch mal melden. Besten Dank für die Erklärungen erstmal. Da ich für dieses Problemchen aber immer noch Amos bemühen muss, komme ich langsam zu dem Schluss, das es mit dessen ADD Befehl irgendwie anderst geht wie gedacht. So muss ich z.B bei jedem Überlauf die aktuellen Summe noch extra um 1 erhöhen. Und irgendwas ist da dann noch zu beachten, was ich bisher aber noch nicht 'rausbekommen habe. Na, dann werd ich wohl noch ein bischen bei Mad_Doc zur Schule gehen müssen. ;)

mfg Palgucker

[ - Antworten - Zitieren - Direktlink - ]

19.03.2004, 12:47 Uhr

Solar
Posts: 3680
Nutzer
Ich würd' ja gerne präziser werden, aber ich kann wahrscheinlich noch weniger AMOS als Du C... ;-)

[ - Antworten - Zitieren - Direktlink - ]

19.03.2004, 16:32 Uhr

Mad_Dog
Posts: 1944
Nutzer
Zitat:
Original von Palgucker:
Na, dann werd ich wohl noch ein bischen bei Mad_Doc zur Schule gehen müssen. ;)


Du meinst bei meinem C-Kurs? Wie gasagt: Wie Prüfsummen in den AmigaOS Filesystemen implementiert sind, weiß ich jetzt auch nicht...
was ich geschrieben habe, war die allgemeine Vorgehensweise.

Übrigens: Mad_Dog nicht mit c.



--

http://www.norman-interactive.com

[ - Antworten - Zitieren - Direktlink - ]

19.03.2004, 17:08 Uhr

Palgucker
Posts: 1342
Nutzer
@ Solar

quote:
Ich würd' ja gerne präziser werden, aber ich kann wahrscheinlich noch weniger AMOS als Du C... ;-)

So sieht das ganze in Amos aus. Auch wenn Du Amos nicht kennen solltest, wird sich Dir dieses Basic-Script mit Sicherheit vollständig erschliessen.
code:
F$='RAM:Test.block'
Open In 1,F$
Laenge=Lof(1)
Reserve As Work 1,Laenge
Bload F$,1
B1=Start(1)                 //Startadresse des Speicherbereiches
Close 1

CHECKSUMPOS=4

Print Hex$(Leek(B1+CHECKSUMPOS))

Loke B1+CHECKSUMPOS,0

For I=0 To Laenge-4 Step 4
OLDSUM=SUM
Add SUM,Leek(B1+I)
If(SUM<OLDSUM) Then Inc SUM // Abfrage ob Überlauf stattfand.
Next 
Print Hex$(-SUM)

Bleibt vielleicht noch anzumerken, das Add und Inc in Amos besonderst Maschinennahe Operationen darstellen, die keinen Overflow auslösen.

mfg Palgucker

[ - Antworten - Zitieren - Direktlink - ]

19.03.2004, 17:28 Uhr

Palgucker
Posts: 1342
Nutzer
@ Mad_Dog

quote:

Du meinst bei meinem C-Kurs? Wie gasagt: Wie Prüfsummen in den AmigaOS Filesystemen implementiert sind, weiß ich jetzt auch nicht...
was ich geschrieben habe, war die allgemeine Vorgehensweise.


Ja, Deinen Kurs meine ich und schaue auch eigendlich täglich mal rein, ob es was neues gibt. Das Du dort natürlich keine speziellen Probleme lösen sollst, ist natürlich klar. Aber er sollte einen schon so weit bringen, das man z.B. Thomas seine Funktion einfach richtig einbindet und ausprobiert. Aber bis jetzt meckert der Compiler, was das Zeug hält.

quote:

Übrigens: Mad_Dog nicht mit c.

Aber ich hab's doch nur gut gemeint. ;)

mfg Palgucker

[ - Antworten - Zitieren - Direktlink - ]

19.03.2004, 17:51 Uhr

Mad_Dog
Posts: 1944
Nutzer
Zitat:
Original von Palgucker:

Ja, Deinen Kurs meine ich und schaue auch eigendlich täglich mal rein, ob es was neues gibt. Das Du dort natürlich keine speziellen Probleme lösen sollst, ist natürlich klar. Aber er sollte einen schon so weit bringen, das man z.B. Thomas seine Funktion einfach richtig einbindet und ausprobiert. Aber bis jetzt meckert der Compiler, was das Zeug hält.


Was thomas hier gepostet hat, ist auch kein komplettes Programm, sondern nur ein Codeschnipsel. Du mußt z.B. <string.h> mit #include <string.h> einbinden, damit der Compiler den Funktiosprototyp von memset kennt... aber ein komplettes Programm ist dieser Code dann trotzdem noch nicht.

Den Kurs werde ich auch noch erweitern, keine Sorge. :) Alles zu seiner Zeit.

--

http://www.norman-interactive.com

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Checksumme berechnen? [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.