Hoi allen,
Ik zit met het volgende vraagstuk.
Voor een project met seriele datacommunicatie, moet ik een checksum calculatie doen.
Nu heb ik het volgende voorbeeld: [waarden in hexadecimaal]
30+31+48+41+4E+4F+56+45+52+03 = 277
Tot hier geen spannende dingen, bovenstaande is een normale som van alle hexwaarden.
Maar, nu moet ik van de uitkomst, de checksum waarde berekenen.
Het voorbeeld laat de volgende formule zien:
checksum = 0-(277 mod 256) = 89
Als ik dit in mijn rekenmachine intoets, krijg ik -21. En als ik de 0- weglaat, gewoon 21, maar da's logisch.
Ik doe dit niet snappen.
Het voorbeeld klopt wel, want het serieel te besturen apparaat [rs485] reageert er prima op.
Alvast bedankt voor het meedenken.
Modulo vraag
Re: Modulo vraag
Je hebt gegeven:
30+31+48+41+4E+4F+56+45+52+03 = 277(hex)
maar ook
277(dec) mod 256(dec) = 21(dec)
Eerst werk je 16-tallig, dan 10-tallig, klopt dat?
Hoe is je checksum precies gedefinieerd?
30+31+48+41+4E+4F+56+45+52+03 = 277(hex)
maar ook
277(dec) mod 256(dec) = 21(dec)
Eerst werk je 16-tallig, dan 10-tallig, klopt dat?
Hoe is je checksum precies gedefinieerd?
Re: Modulo vraag
Dit bedoel je?
Meer staat er niet echt in.
De hex waarden uit het voorbeeld zijn trouwens ascii-hex waarden, ik weet niet of dat wat uitmaakt.
De uitkomst [89] wordt voor verzending vertaald naar ascii-hex [38 39].
Meer staat er niet echt in.
De hex waarden uit het voorbeeld zijn trouwens ascii-hex waarden, ik weet niet of dat wat uitmaakt.
De uitkomst [89] wordt voor verzending vertaald naar ascii-hex [38 39].
Re: Modulo vraag
Je hebt een rij van N+1 bytes ~= een rij getallen van 0(dec) t/m 255(dec)
ofwel een rij getallen van 0(hex) t/m FF(hex)
Deze kan je weergeven als:
B0 (= start-of-frame) blijft buiten beschouwing
B1 t/m B[N-1] worden eerst bij elkaar opgeteld. Hexadecimaal levert dit in je voorbeeld:
30+31+48+41+4E+4F+56+45+52+03 = 277
277(hex) modulo 256(dec) = 277(hex) modulo 100(hex),
want 256(dec) = 100(hex).
Hexadecimaal neem je dus 277 modulo 100 = 77(hex).
Dit zijn hexadecimaal de laatste 2 cijfers van het antwoord van je optelling.
Je checksum (= B[N]) wordt dan hexadecimaal:
0 - 77 (mod 100) = -77 (mod 100) = 100 - 77 (mod 100) = 89 (mod 100)
Dus: B[N] = 89(hex).
Ter controle: tel B[1] t/m B[N] bij elkaar op en je krijgt: 277 + 89 = 300 = 0 (mod 100)
Je blijft dus hexadecimaal werken.
Uiteraard kan je ook vertalen naar 10-tallig, maar dan moet je het eindresultaat terugvertalen naar 16-tallig. Je krijgt dan:
77(hex) = 119(dec)
dan decimaal:
0 - 119 (mod 256) = -119 (mod 256) = 256 - 119 (mod 256) = 137.
Dan terug naar hex: 137(dec) = 89(hex).
Noot: je rekenmachine zegt 277 mod 256 = 21, maar dit klopt als je volledig 10-tallig werkt, terwijl je hier 277(hex) mod 256(dec) wil weten.
PS:
Een byte (= 8 bits getal) heeft een waarde van 0(dec) t/m 255(dec) ofwel 0(hex) t/m FF(hex).
De ASCII codering geeft aan elk van deze 256 getallen een betekenis in de vorm van letters, cijfers, symbolen, etc.
Zo wordt het getal 38(hex) gecodeerd als karakter '8', en 39(hex) als '9'.
Ik verwacht dat 89(hex) direct verstuurd wordt over je kanaal, en niet de 2 karakters 8 en 9.
ofwel een rij getallen van 0(hex) t/m FF(hex)
Deze kan je weergeven als:
B0 (= start-of-frame) blijft buiten beschouwing
B1 t/m B[N-1] worden eerst bij elkaar opgeteld. Hexadecimaal levert dit in je voorbeeld:
30+31+48+41+4E+4F+56+45+52+03 = 277
277(hex) modulo 256(dec) = 277(hex) modulo 100(hex),
want 256(dec) = 100(hex).
Hexadecimaal neem je dus 277 modulo 100 = 77(hex).
Dit zijn hexadecimaal de laatste 2 cijfers van het antwoord van je optelling.
Je checksum (= B[N]) wordt dan hexadecimaal:
0 - 77 (mod 100) = -77 (mod 100) = 100 - 77 (mod 100) = 89 (mod 100)
Dus: B[N] = 89(hex).
Ter controle: tel B[1] t/m B[N] bij elkaar op en je krijgt: 277 + 89 = 300 = 0 (mod 100)
Je blijft dus hexadecimaal werken.
Uiteraard kan je ook vertalen naar 10-tallig, maar dan moet je het eindresultaat terugvertalen naar 16-tallig. Je krijgt dan:
77(hex) = 119(dec)
dan decimaal:
0 - 119 (mod 256) = -119 (mod 256) = 256 - 119 (mod 256) = 137.
Dan terug naar hex: 137(dec) = 89(hex).
Noot: je rekenmachine zegt 277 mod 256 = 21, maar dit klopt als je volledig 10-tallig werkt, terwijl je hier 277(hex) mod 256(dec) wil weten.
PS:
Een byte (= 8 bits getal) heeft een waarde van 0(dec) t/m 255(dec) ofwel 0(hex) t/m FF(hex).
De ASCII codering geeft aan elk van deze 256 getallen een betekenis in de vorm van letters, cijfers, symbolen, etc.
Zo wordt het getal 38(hex) gecodeerd als karakter '8', en 39(hex) als '9'.
Ik verwacht dat 89(hex) direct verstuurd wordt over je kanaal, en niet de 2 karakters 8 en 9.
Re: Modulo vraag
Super!
Bedankt voor je uitgebreide uitleg, ik snap het nu helemaal.
Nu kan ik het verwerken in mijn programma.
Handmatig al een paar voorbeelden uitgerekend en verstuurd, werkt uitstekend.
Klasse, ik ben blij
(De wiskunde leraar van de middelbare school kan tevreden zijn, al is dat voor mij al 15 jaar geleden)
Bedankt voor je uitgebreide uitleg, ik snap het nu helemaal.
Nu kan ik het verwerken in mijn programma.
Handmatig al een paar voorbeelden uitgerekend en verstuurd, werkt uitstekend.
Klasse, ik ben blij
(De wiskunde leraar van de middelbare school kan tevreden zijn, al is dat voor mij al 15 jaar geleden)
Re: Modulo vraag
.Nu kan ik het verwerken in mijn programma
Blijkbaar ga je iets programmeren. Als je programmeertaal een één byte datatype ondersteunt, kun je de (dure!) modulo berekening overslaan:
Gebruik één byte voor de som van de B's. (datatype BYTE of CHAR, afhankelijk van de programmeertaal).
B.v. 30+31+48+41+4E = 138 (hex). Maar dit past niet in één byte, waardoor de overflow tijdens de optelling vanzelf wegvalt, waardoor je 38 (hex) overhoudt. Dit is gelijk aan de (mod 256) bewerking.
Op deze manier wordt 30+31+48+41+4E+4F+56+45+52+03 automatisch 77 (hex), zonder dat je een modulo bewerking hoeft uit te voeren.
Als je programmeertaal géén één byte datatype ondersteunt kun je nog de veel goedkopere AND operator gebruiken i.p.v. de modulo:
n mod 256 = n AND 255