Hallo, habe ein Problem. Programiere in C (C99) Keil. Muss eine große Zahl dezimal in hex umrechrechnen. Die Werte stehen im 5 Byte Array. Also ArrayDez[5] in ein ArryHex[5] umrechnen. z.b die Dezimalzahl im Array 99|99|99|99|99 => 02|54|0B|E3|FF (hex) Problem ist es gibt nur Variabel unsigned long = 4 byte im Keil C99 gibt Aber 5 Byte in eine 4 Byte unsigned long geht nicht. Der Umrechnungsalgoritmus ist mir soweit klar zahl/16 Rest usw. Aber ich die ist zu "groß"....? Jemand eine Idee? Danke im Vorraus. Roger
:
Gesperrt durch Moderator
Roger P. schrieb: > Hallo, > > habe ein Problem. Programiere in C (C99) Keil. > Muss eine große Zahl dezimal in hex umrechrechnen. Die Werte stehen im 5 > Byte Array. Also ArrayDez[5] in ein ArryHex[5] umrechnen. > > z.b die Dezimalzahl im Array 99|99|99|99|99 => 02|54|0B|E3|FF (hex) > > Problem ist es gibt nur Variabel unsigned long = 4 byte im Keil C99 gibt > > Aber 5 Byte in eine 4 Byte unsigned long geht nicht. > > Der Umrechnungsalgoritmus ist mir soweit klar zahl/16 Rest usw. > Aber ich die ist zu "groß"....? > > Jemand eine Idee? > > Danke im Vorraus. > > > Roger Roger P. schrieb: > Aber 5 Byte in eine 4 Byte unsigned long geht nicht. Dann nimm doch zwei 4 Byte unsigned long
Hallo >>Dirk F. (dirkf) >>Dann nimm doch zwei 4 Byte unsigned long Wie soll das gehen? Der Algorithmus beginnt mit Zahl / 16 z.B 9999999999 / 16 = ... Roger
??? Oder ein 5-Byte-Array... das hab ich doch...
Offiziell kennt C99 doch long long?
:
Bearbeitet durch User
Nein- mein C51 Keil kann das nicht. Maximal Variable ist 4 Byte lang. Das ist ja der Kern des Problems!
:
Bearbeitet durch User
Roger P. schrieb: > 02|54|0B|E3|FF Das sind aber 10 Bytes, nicht 5. Also eher ein "char hexNum [10];".
:
Bearbeitet durch User
Niklas G. schrieb: > Das sind aber 10 Bytes, nicht 5. Ich sehe da fünf, das wird ja kein String (Text) sein.
Harald K. schrieb: > das wird ja kein String (Text) sein. Naja, er wollte "hex". Heißt also im Speicher sollen Hexadezimalziffern stehen, also 0-9 A-F. Also würde ich davon ausgehen, dass 1 Byte im Speicher = 1 Hexadezimalziffer. 2 Bytes im Speicher = 2 Hexadezimalziffern = 1 dargestelltes Byte.
:
Bearbeitet durch User
Hallo Das ist ein 5 byte unsigned-Char Array. Das einzelne ArrayByte- also jedes Byte geht von 00-99 dezimal. Also eine simple 10 stellige dezimale Zahl in einen 5 Byte Array. Roger
Roger P. schrieb: > in einen 5 Byte Array. In ein 5 Byte-Array passt keine hexadezimale Zahl mit 10 Ziffern (9 würden reichen).
Roger P. schrieb: > Also eine simple 10 stellige dezimale Zahl in einen 5 Byte Array. Also die beknacktmöglichste Art, so eine Zahl dort unterzubringen.
Roger P. schrieb: > Das ist ein 5 byte unsigned-Char Array. Roger P. schrieb: > Problem ist es gibt nur Variabel unsigned long = 4 byte im Keil C99 gibt Versteh ich nicht...
Leute - was dikutiert ihr nur... Wieso so das so steht ist doch egal... ( Es wird von Chipkarte so gelesen) Das Array hat 5 Byte. Das ist nun mal so. Da stehen die Zahl als dezimal drin. Also 10 stellig dezimal. Ja wenn die umgerechnet ist werden "nur" 9 Stellen wieder "gebraucht". So ist das und es sit kein Problem. Vorher 99|99|99|99|99 Nachher 02|54|0B|E3|FF Ich soche einen Rechenalgorithmus der mit Compilervar. von 4 Byte länge klarkommt.
> Problem ist es gibt nur Variabel unsigned long = 4 byte im Keil C99 gibt
Versteh ich nicht...
Der Keil C51 für 8051er kann nur 1,2,4 Byte signed oder unsigned
Variablen.
Das ist nun Fact und läßt sich nicht ändern. Eine Diskussion weiso udn
weshalb ist nicht zielführend.
mfg
Roger
Solange Zahl > 4.294.967.296 dies abziehen (in BCD), das geht maximal 2 mal. Danach die Zahl in dezimal 4 byte konvertieren und in hex umrechnen. Das 5. Hex byte entsprechend der Abzüge auf 0, 1 oder 2 setzen.
:
Bearbeitet durch User
Dann wäre es vielleicht zielführender, wenn du dein Problem vernünftig beschreibst und vielleicht auch mal eine Rechtschreibkontrolle durchführst, bevor du deinen Beitrag veröffentlichst. ;-)
wie groß ist denn die maximalmögliche Zahl in diesen 5 Byte?
Roger P. schrieb: > Da stehen die Zahl als dezimal drin. Also 10 stellig dezimal. Tut sie halt nicht, wenn das hier > Vorher 99|99|99|99|99 > Nachher 02|54|0B|E3|FF eine hexadezimale Darstellung des Speicherinhalts sein soll. Dann steht die Zahl da als packed BCD drin. https://en.wikipedia.org/wiki/Binary-coded_decimal#Packed_BCD Und Du brauchst als Zieldatentyp halt einen, der größer ist als 32 Bit. Der heißt (u)int64_t. Wenn Dein Compiler das nicht kann, musst Du das ganze von Hand klöppeln.
>> musst Du das ganze von Hand klöppeln. das ist ja meine Frage! Einen Ansatz? Ich weis nicht was daran nicht richtig beschrieben ist. Man liest von einem Speichermedium 5 Byte raus. Das sind z.B 7952632952 und umgerechnet sollen wieder 01DA038C78 im Array stehen. Vorraussetzung der C Compiler kann nur als größste Variable 4 Byte Nun bitte keine Zahlenkunde! Wenn einer eine Rechenwegansatz mit diesen Vorraussetzungen hat ... bitte >>wie groß ist denn die maximalmögliche Zahl in diesen 5 Byte? 0000000000 - 9999999999 Eine Kartennummer dezimal auf einer Chipkarte. Das ist nunmal so. Roger
:
Bearbeitet durch User
Roger P. schrieb: >>>wie groß ist denn die maximalmögliche Zahl in diesen 5 Byte? > 0000000000 - 9999999999 > > Eine Kartennumer dezimal auf einer Chipkarte. Das ist nunmal so. ich weiß dass Nachfragen nicht erlaubt sind, aber musst du das wirklich umrechnen? Wenn dein Compiler nur 32Bit kann, musst du dir dann eine eigene Zahlendarstellung überlegen. Wenn du damit Rechnen willst, auch eigene Rechenoperationen für diese Darstellung programmieren. Aber ich glaube nicht, dass du die Umrechnung wirklich brauchst (auch wenn ich dafür wieder ein paar minus ernte)
:
Bearbeitet durch User
Hallo, Doch leider muss ich diese umrechnen und in Hex weiterreichen... Ist sch... weis. Sonst wäre das ja mit sprintf leicht möglich.. Float32 geht auch nicht. Roger
Jede BCD-Stelle hat ihre Wertigkeit: die rechte 0, die zweitrechte 0d100=0x64, die drittrechte 0d10000=0x2710 usw. Wandelt man also jede BCD-Stelle einzeln um, multipiziert mit ihrer Wertigkeit, und summiert - oder habe ich das falsch verstanden bzw. sehe das zu einfach?
Roger P. schrieb: > Doch leider muss ich diese umrechnen und in Hex weiterreichen... Was zwingt Dich dazu?
>>Was zwingt Dich dazu?
Große bestehende Infrastrukturen und Systeme in Unternehmen/
Zielsystemen die nicht zu ändern sind.
Roger
Roger P. schrieb: > Große bestehende Infrastrukturen und Systeme in Unternehmen/ > Zielsystemen die nicht zu ändern sind. Aha. Die schreiben also vor, daß ein nicht existierender Datentyp für irgendwas verwendet werden soll. Warum nur habe ich den Verdacht, daß Du die Aufgabenstellung nicht verstanden hast?
>>Harald K. (kirnbichler)
Klar - ich habe die Aufgabenstellung nicht verstanden.
Was soll das?
Hast du Lösungsansätze? Deine AW haben hier nicht einen Millimeter zur
Lösung beigetragen.
Die Umgebung und Voraussetzung sind nicht zu ändern. Das ist nunmal so.
Roger
Roger P. schrieb: > Hast du Lösungsansätze? Deine AW haben hier nicht einen Millimeter zur > Lösung beigetragen. Natürlich haben die das. Nimm (u)int64_t. Die Transferleistung, davon dann die unteren fünf Bytes zu verwenden, solltest Du hinbekommen. Und den Hinweis, daß Dein Eingangsdatenformat "packed BCD" heißt, habe ich Dir auch gegeben. Wenn Dir das nicht zur Lösung verhilft, solltest Du über ein anderes Betätigungsfeld nachdenken.
Mir ist dazu nur ein trickreicher Algorithmus für die umgekehrte Richtung eingefallen https://www.mikrocontroller.net/index.php?title=AVR_Arithmetik#Bin%C3%A4r-zu-BCD-Umwandlung speziell hier: https://en.wikipedia.org/wiki/Double_dabble Den gibt es anscheinend auch für die umgekehrte Richtung: "The algorithm is fully reversible. By applying the reverse double dabble algorithm a BCD number can be converted to binary."
>> von Harald K. (kirnbichler) >> Nimm (u)int64_t. Scheinst es nicht zu verstehen. Es gibt keine Variable mit mehr als 32bit!!! Nix uint64! Der Compiler macht das nicht. Du bist der einzige der das hier nicht verstanden hat. Denk mal nach... Roger
:
Bearbeitet durch User
Mach die Rechnung einfach zu Fuß, wie man es auch in Assembler machen würde. Du hast ein Array aus 5 Bytes packed BCD und ein Array aus 5 Bytes als Ziel. Und dann in einer Schleife: 1. Byte BCD * 2 , d.h. addieren mit sich selber mit Dezimalkorrektur. Dann das 2. Byte + Übertrag vom ersten Byte usw. bis zum 5 Byte. Der Übertrag vom 5. Byte wird dann in das Zielarray von rechts geschoben. Und das ganze in einer Schleife 40*. Danach ist das Dezimalarray 0 und das Zielarray enthält den Binärwert. Alle Operationen sind also nur über jeweils 1 Byte und somit prima in C zu erledigen.
Ich kenne das, manchmal reichen auch 64bit nicht aus. Dann muss man das zu Fuß machen. Such mal nach "large integer arithmetic in c", da findest du z.B. so was hier: https://www3.cs.stonybrook.edu/~skiena/392/programs/bignum.c als Anschauungsobjekt. Diese Mimik könntest mit den n Dezimal-Ziffern füllen und die zugehörigen Hex-Ziffern dann heraus-shiften.
:
Bearbeitet durch User
Kannst du die Zahl nicht einfach überlaufen lassen und merkst dir dann, wie oft?. Oder fängst eben erst rechts mit den kleinerwertigen Zahlen an und betrachtest das getrennt in zwei oder vier Blöcken und bastelst alles im Nachgang wieder zusammen. Werden die Infos als ASCII in „lesbarer Form“ über die serielle versendet oder kommen dort schon die Byte als „undruckbare“ Zeichen an? (Arduino-like serial.write vs. Serial.print zB)
Es muss wirklich unbedingt 8051 sein? ARM-Compiler können uint64_t und das Problem ist ratzfatz gelöst.
Roger P. schrieb: > Du bist der einzige der das hier nicht verstanden hat. Denk mal nach... Hast Du Dir wenigstens schon mal die Mühe gemacht, nachzusehen, was BCD ist? Dein Umgangston jedenfalls legt nahe, daß Du keine Hilfe willst.
HAllo,
An der Hardware und Infrastruktur ist nicht zu rüttel...
Kann auch keine zehntausende Chipkarten ändern...
Ich übe hier nicht auf dem Steckbrettchen sondern müssen ein äteres
bestehendes System anpassen...
Übrigens wie Andreas B. geschreiben...
>>Ich kenne das, manchmal reichen auch 64bit nicht aus.
steht man dann auch mit uint64 vor dem gleichen Problem.
Roger
Roger P. schrieb: > Scheinst es nicht zu verstehen. > Es gibt keine Variable mit mehr als 32bit!!! Nix uint64! > Der Compiler macht das nicht. > > Du bist der einzige der das hier nicht verstanden hat. Denk mal nach... Nee, du bist der einzige, der immer noch nicht verstanden hat: - daß man da halt seine Rechenkünste aus der Grundschule auspacken muß, um das zu lösen - das hier im Forum dir niemand die Hausaufgaben macht. Du machst sowas ja offensichtlich nicht beruflich, aber etwas mehr Eigeninitiative darfs auch bei Hobby schon sein. Sonst ist das das falsche Hobby. Oliver
:
Bearbeitet durch User
>> Harald K. >>Hast Du Dir wenigstens schon mal die Mühe gemacht, nachzusehen, was BCD >>ist? >>Dein Umgangston jedenfalls legt nahe, daß Du keine Hilfe willst. Deine Wikipedia Belehrung kannst du dir sparen. Hast du etwas brauchbares beizutragen? Einen Ansatz Algorithmus? Die Leute die mitreden wollen sollten erstmal die Problemstellung verstanden haben... MFG Roger
Beitrag #7718450 wurde vom Autor gelöscht.
Lieber Ralf G Wenn du hier so groß tönst Dann zeig mit mal im Ansatz wie Mir Ist auch der normale Rechenweg zur Umwandlung Dez => Hex klar Bild Anhang. So und nun mal 99999999999999 /16 wenn man nur uint32 hat. Na los ich warte.. aber wahrscheinlich kommt nix! Roger
Roger P. schrieb: > Die Leute die mitreden wollen sollten erstmal die Problemstellung > verstanden haben... Etwas nicht zu wissen ist keinen Schande, aber dumm und arrogant ist eine ganz ungute Kombination. Aber egal, hier nochmals ganz einfach, zum mitdenken: Das Problem, daß man mal mit Zahlen rechnen muß, die größer sind als der Wertebereich des größten verfügbaren Integer-Datentyps, ist so alt wie die Computer-Rechnerei. Daher gibt es dafür auch schon seit langem Algorithmen dafür. Einen davon lernt man in der ersten Klasse in der Schule. Der ist sogar noch älter als die Computer, aber trotzdem nicht der schlechteste. Hast du es jetzt verstanden? Falls du dann doch google benutzen möchtest, wäre das passende Suchwort dafür "big integer" oder "large integer". Oliver
Wie wäre es damit erst DEZ -> BIN zu rechnen? Dann muss man nur multiplizieren und addieren. Aus einer 5-Byte-Binärzahl eine 10-Byte-Hexzahl zu machen ist dann einfach.
>> Oliver S >>Daher gibt es dafür auch schon seit langem >>Algorithmen dafür. Einen davon lernt man in der ersten Klasse in der >>Schule. Der ist sogar noch älter als die Computer, aber trotzdem nicht >>der schlechteste. Dann teile uns die doch mal hier bitte mit... Roger
Roger P. schrieb: > z.b die Dezimalzahl im Array 99|99|99|99|99 Meinst du BCD oder wie soll das verstanden werden? > Der Umrechnungsalgoritmus ist mir soweit klar zahl/16 Rest usw. Sicher?
Roger P. schrieb: > Deine Wikipedia Belehrung kannst du dir sparen. Ach, das ist eine Belehrung. Nein, Kindchen, das ist ein Teil des Grundlagenwissens, das Dir fehlt.
Roger P. schrieb: > Dann teile uns die doch mal hier bitte mit... Erst, wenn du deinen Grundschulabschluß fertig hast. Aber dann kannst du ja auch selber schriftlich dividieren... Oliver
Leute, ich lese von einer Chipkarte 5 Byte und stecke diese in ein 5Byte Array. Kann die nicht in eine Uint32 stecken. Diese 5 Byte sind von 0 bis 9999999999 Normalerweise würde man diesen Algorithmus (Bild zuvor) ja einfach durhführen können. Aber nur bis uint32.
Roger P. schrieb: > Deine Wikipedia Belehrung kannst du dir sparen. Hast du etwas > brauchbares beizutragen? Einen Ansatz Algorithmus? Mit dem richtigen Suchbegriff "BCD" hättest du eine Chance, einen fertigen Algorithmus dafür zu finden. (packed) BCD ist keine Neuerfindung. Du brauchst für die Binärdarstellung einer 10-stelligen Dezimalzahl nicht mehr als 34 Bit.
>>Oliver S
Willst nur trollen - wissen oder beitragen kannst du nix
@ Mod. bitte handeln...
Roger P. schrieb: > Dann teile uns die doch mal hier bitte mit... "Schriftliches Dividieren". Das funktioniert auf dem Mikrocontroller ganz genauso wie im Schulheft und geht mit jeder beliebigen Zahlenlänge.
>>Du brauchst für die Binärdarstellung einer 10-stelligen Dezimalzahl >>nicht mehr als 34 Bit. Und wenn man nur 32 hat? Dann.....? Roger
Roger P. schrieb: > Mir Ist auch der normale Rechenweg zur Umwandlung Dez => Hex klar Mir ist nicht mal klar, was du denn mit "Hex" und "Dez" überhaupt meinst. Für mich ist das nur eine unterschiedliche **Schreibweise** ein und derselben Zahl. Genauso, wie mal diese Zahl auch oktal oder binär darstellen könnte. Roger P. schrieb: > z.b die Dezimalzahl im Array 99|99|99|99|99 Wie ist das gemeint? Stehen da in den 5 Byte die Werte 0x99, 0x99, 0x99, 0x99 und 0x99 und wenn du diese Zahl mit Worten auf ein Blatt Papier schreiben müsstest, dann wären das "neun Milliarden, neunhundertneunundneunzig Millionen neunhundertneunundneunzig Tausend und neunhundertneunundneunzig"? Und dein Problem ist, dass in einen uint32 nur knapp über 4 Milliarden passen? Und viel interessanter: woher bekommst du eine Zahl in diesem (BCD-)Format? Roger P. schrieb: > Und wenn man nur 32 hat? > Dann.....? Dann ist es eh' witzlos, diese Aufgabe mit einem Compiler zu machen, der nicht mit uint_64 aka long long umgehen kann. Denn was tust du hinterher mit deiner handgestrickten 34-Bit-Zahl? Die musst du in jedem weiteren Rechenschritt händisch selber neu bearbeiten.
:
Bearbeitet durch Moderator
Lothar M. schrieb: > Und viel interessanter: Woher bekommst du eine Zahl in diesem > (BCD-)Format? Roger P. schrieb: > ich lese von einer Chipkarte 5 Byte
Roger P. schrieb: > Na los ich warte.. aber wahrscheinlich kommt nix! > > Roger Ich glaube fast, dass dir niemand die Lösung mundgerecht liefern wird. Ehrlich gesagt gefällt mir dein Ton auch nicht, möchtest du Hilfe haben oder nur rumpöbeln? Das Problem mit der large-integer-arithmetic hatte ich halt mal vor vielen Jahren, da waren es 101 Bit Rohdaten aus denen ich die Nutzdaten raus-shiften wollte. Was hat denn Deine Recherche bezüglich "large integer arithmetic" geliefert? In c++ wird es sicher auch viele Beispiele und Libs im Netz geben, aber ob das für Deinen Kompiler passt, weiß ich nicht.
Dietrich L. schrieb: > Roger P. schrieb: >> ich lese von einer Chipkarte 5 Byte Oha, das ist mir in der Salamitaktik entgangen... Und was soll dann mit dieser "Zahl" passieren? Muss damit gerechnet werden? Oder ist das nur eine Kennung oder eine ID? Davon abgesehehn kann man auch mit BCD-Zahlen tadellos rechnen. Das tut dann natürlich auch nicht der Compiler.
:
Bearbeitet durch Moderator
Lothar M. schrieb: > Und was soll dann mit dieser "Zahl" passieren? Muss damit gerechnet > werden? Die muss aus ominösen Gründen in ein anderes (nicht platzsparenderes) Format überführt werden, weil: Roger P. schrieb: > Große bestehende Infrastrukturen und Systeme in Unternehmen/ > Zielsystemen die nicht zu ändern sind. Klar. Wenn z.B. die Chipkarte eine GUID liefern soll, dann kann man die nicht einfach so lassen wie sie ist, sondern muss sie umrechnen. Weil das ja klar ist oder so. Wie schon geschrieben: Ich bin mir sehr sicher, daß die Aufgabenstellung komplett missverstanden wurde.
Roger P. schrieb: > Willst nur trollen - wissen oder beitragen kannst du nix Wenn du auch nur einen einzigen der vielen Hinweise zum Thema oder eins der Stichwörter, die hier schon gefallen sind, aufgenommen hättest, wärst du jetzt mit der Aufgabe fertig. Es ist dein Problem, nicht unseres. Die Lösung zu deinem Problem ist "schriftliches dividieren". Das lernt man in der Grundschule. Algorithmen dazu stehen aber auch im Netz, z.B. in der wikipedia, aber die ignorierst du ja auch. Suchen und finden sind allerdings dermaßen einfach, daß dir das keiner abnimmt. Das musst du schon selber machen. Oliver
Roger P. schrieb: > Die Leute die mitreden wollen sollten erstmal die Problemstellung > verstanden haben... Dann stelle doch Dein Problem auch so dar, dass man Dir weiterhelfen kann. Roger P. schrieb: > Eine Kartennummer dezimal auf einer Chipkarte. Das ist nunmal so. Ah, OK, also eigentlich keine "Zahl" (obwohl es Karten-_Nummer_ heißt), sondern eine Folge von Dezimalziffern. Nun meine Frage: was musst Du selbst mit der Kartennummer tun? Vermutlich nicht rechnen, oder? Oder hat deine Aufgabe mit Verschlüsselung zu tun? Ich habe jetzt nicht den ganzen Thread gelesen, deshalb nochmal die Frage, ob die Ziffern BCD-codiert sind? Und noch eine Frage: wenn Du da irgend was an eine Schnittstelle weiterreichen musst, welches Format erwartet denn diese Schnittstelle? ciao Marci
Hallo Ich lese diese 5 byte aus der Karte und die sind per Definition eine Dezimalzahl! ( Es kommen keine Pseudotetraden A bis F vor) Also eine Zahl von 0-99999999999999. Das ist die Kartennummer die auch aussen aufgedruckt ist. Das ist die Vorgeschichte. Nun muss die zur Hexzahl gewandelt werden. Roger
>> Oliver S
Du redet nur daher und trollst. Nix hast oder kannst - aber auch gar
kein Ansatz. Du laberst nur was von Grundschulmathe.
der einzige Ansatz den ich mir Anschaue ist von Andreas B. und Peter D.
Roger
Roger P. schrieb: > Nun muss die zur Hexzahl gewandelt werden Und, nochmal blöd gefragt, obwohl schon am Anfang des Threads erörtert: Du kannst das NICHT wieder in einem 5-Byte-Array speichern? ciao Marci
Roger P. schrieb: > Nun muss die zur Hexzahl gewandelt werden. Glaub' ich nicht. Genau das wirst Du einfach nicht kapiert haben.
> einen einzigen der vielen Hinweise zum Beispiel meinen Vorschlag oben "reverse double dabble" https://en.wikipedia.org/wiki/Double_dabble#Reverse_double_dabble Reverse double dabble (BCD to binary) "Hex" ist nur eine Darstellungsweise, besser nach "binary" suchen. Beliebig lange Zahlen, nur rechts schieben, 4-Bit-Subtraktionen und 4-Bit-Vergleiche. In Assembler wäre das normal und nur durch den Speicherplatz (und die Rechenzeit) beschränkt.
Doch nachher soll die Kartennummer im gleichen oder neuen Array stehen Geht doch nur in array wieder zu speichern da > 4 Byte uint Vorher 99|99|99|99|99 Nachher 02|54|0B|E3|FF Roger
:
Bearbeitet durch User
Hallo Roger, ich muss jetzt doch nochmal nervig fragen: Du hast also 5 Bytes, in denen die Dezimalzahl steht. Kannst Du mal bitte darstellen, welchen Wert das jeweilige Byte (von 0-255) hat, wenn da z.B. die Dezimalzahl 123456 drin gespeichert ist? Danke. ciao Marci
Roger P. schrieb: > Du redet nur daher und trollst. Nix hast oder kannst - aber auch gar > kein Ansatz. Du laberst nur was von Grundschulmathe. > > der einzige Ansatz den ich mir Anschaue ist von Andreas B. und Peter D. Wenn du dir den von Andreas B verlinkte Code angeschaut hättest, dann hättest du bemerkt, daß das genau der Grundschulmathe-Algorithmus ist. Erste Ziffer des Dividenden durch den Divisor teilen, Ergebnis merken, Rest auch. Ergebnis mal 10, Rest mal 10, nächste Ziffer "von oben holen", zum 10-fachen Rest addieren, und alles von vorn, bis fertig. Klingt einfach, ist auch so. Da du allerdings 32 Bit zur Verfügung hast, könnte man das für deine 10 Ziffern in nur zwei Schritten erledigen, aber die Transferleistung dazu ist dann schon etwas oberhalb des Grundschulniveaus. Wie du aus dem Ergebnis dann deine Hex-Zahl bekommst, ebenso. Wobei, selbst das steht schon hier im Thread. Oliver
:
Bearbeitet durch User
Hi Roger, OK, ich denke ich habe es kapiert: bei 99999.... steht in jedem Byte der Dezimalwert 99, also hex 63. Ist das so? Es wundert mich, dass das tatsächlich so auf der Karte gespeichert ist. ciao Marci
:
Bearbeitet durch User
Marci W. schrieb: > OK, ich denke ich habe es kapiert: Nein, hast Du nicht, es steht in jedem Byte der Wert 0x99. Das nennt sich packed BCD, jedes Nibble kann nur einen Zahlenwert von 0..9 annehmen.
Harald K. schrieb: > Nein, hast Du nicht, es steht in jedem Byte der Wert 0x99. Das nennt > sich packed BCD das vermuten wir natürlich (alles andere wäre schon seltsam), explizit bestätigt hat Roger das jedoch noch nicht! Deshalb habe ich ja auch nochmal nachgehakt: Marci W. schrieb: > Ich habe jetzt nicht den ganzen Thread gelesen, deshalb nochmal die > Frage, ob die Ziffern BCD-codiert sind? ciao Marci
Marci W. schrieb: > explizit bestätigt hat Roger das jedoch noch nicht! Das wird er auch nicht tun, weil er diese "Wikipedia-Belehrung" strikt ablehnt.
Moin, Christoph db1uq K. schrieb: >> einen einzigen der vielen Hinweise > > zum Beispiel meinen Vorschlag oben "reverse double dabble" > https://en.wikipedia.org/wiki/Double_dabble#Reverse_double_dabble > > Reverse double dabble (BCD to binary) > "Hex" ist nur eine Darstellungsweise, besser nach "binary" suchen. > > Beliebig lange Zahlen, nur rechts schieben, 4-Bit-Subtraktionen und > 4-Bit-Vergleiche. In Assembler wäre das normal und nur durch den > Speicherplatz (und die Rechenzeit) beschränkt. Ich erhoehe die Bewertung um eins und will sehen... scnr WK
Roger P. schrieb: > Große bestehende Infrastrukturen und Systeme in Unternehmen/ > Zielsystemen die nicht zu ändern sind. Das beantwortet nicht die Frage: Lothar M. schrieb: > Und was soll dann mit dieser "Zahl" passieren? Muss damit gerechnet > werden? Oder ist das nur eine Kennung oder eine ID?
Leute, ich kann euch zwar nicht bei der Umwandlung helfen, aber ich weiß welches Problem er hat: Der RFID-Leser liefert tatsächlich 5 Bytes Packed BCD, d.h. 0x12 0x34 0x56 0x78 0x90, entsprechend Kartennummer 1234567890. Das anzusteuernde Gerät braucht aber eine Zahl, nicht BCD. Die wird vmtl. via Serieller Schnittstelle geliefert und kommt nur mit einer Zahl klar, d.h. dort muss dez. 1234567890 als Hex angeliefert werden, d.h. ein Text "0x499602d2". Sein Problem ist das die letzte Kartennummer 0x99 0x99 0x99 0x99 0x99 sein kann, also dezimal "9999999999", was für den anderen Teilnehmer als "0x2540be3ff" ankommen muss, und das sind mehr als 4 Bytes. Man könnte evtl. prüfen, ob man den Leser nicht umkonfigurieren kann, manche können das besser. Wenn's nur darum geht einen Adapter zu programmieren, dann wäre das mit selbstgebauter Arithmetik vmtl. schnell gemacht.
Marci W. schrieb: > ??? Roger P. schrieb: > Deine Wikipedia Belehrung kannst du dir sparen. Jens M. schrieb: > Das anzusteuernde Gerät braucht aber eine Zahl, nicht BCD. Die wird > vmtl. via Serieller Schnittstelle geliefert und kommt nur mit einer Zahl > klar, d.h. dort muss dez. 1234567890 als Hex angeliefert werden, d.h. > ein Text "0x499602d2". Das ist unwahrscheinlich. Das Gerät wird genausogut mit der Zahl 0x1234567890 zurechtkommen, wie es mit der Zahl 0x00499602d2 zurechtkommt. Der Unterschied ist nur eine andere Interpretation der fünf Bytes.
Harald K. schrieb: > Das Gerät wird genausogut mit der Zahl > 0x1234567890 zurechtkommen, wie es mit der Zahl 0x00499602d2 > zurechtkommt. Der Unterschied ist nur eine andere Interpretation der > fünf Bytes. Ja. Aber was machst du, wenn der Kollege an einem Terminal mit seiner 08154711 arbeiten soll, am anderen aber die 135612177 benutzen muss? Unpraktisch... Die eine Kiste spricht halt PackedBCD, die andere Hex. In beiden Fällen brauchts aber die gleiche Zahl, nur eben anders dargestellt.
:
Bearbeitet durch User
Jens M. schrieb: > Die eine Kiste spricht halt PackedBCD, die andere Hex. Genau daran glaub' ich nicht. Die Aufgabestellung ist recht sicher falsch verstanden worden.
Hallo, das ist nicht di UID sondern die Kartennummer die auch aussen aufgedruckt ist. Die ist 10 stellig. In Speicher der Karte ist diese aufgedruckte Kartennummer mit anderen Infos abgelegt. Das macht der Kartenhersteller eben so. Diese Nummer ist eben in 5 Byte abgelegt. jedes Byte "geht" dezimal von 0-99 zu definieren. Also habe ich ab einer dezimalen Kartennummer >00 99 99 99 99 ein Problem bei der Umwandlung in Hexadezimale darstellung. @ Jens M So ist es. >>Genau daran glaub' ich nicht. Die Aufgabestellung ist recht sicher >>falsch verstanden worden. Bullshit Roger
:
Bearbeitet durch User
Moin, Roger P. schrieb: > Also habe ich ab einer dezimalen Kartennummer >00 99 99 99 99 ein > Problem bei der Umwandlung in Hexadezimale darstellung. Ja, aber doch nur weil du nicht schaffst, diesen Algorithmus: > Reverse double dabble (BCD to binary) > Right shift into the output binary > For each group of four input bits: > If group >= 8 subtract 3 from group zu implementieren, oder was sehe ich da falsch? scnr, WK
:
Bearbeitet durch User
>> Reverse double dabble
Ja - das muss ich mir jetzt anschauen...
Roger
Wenn ich die Aufgabestellung richtig verstanden habe, sollte die Konvertierung folgendermaßen möglich sein:
1 | #include <stdio.h> |
2 | #include <stdint.h> |
3 | |
4 | void bcd2bin(uint8_t bcd[5], uint8_t bin[5]) { |
5 | uint32_t tmp=0; |
6 | for (uint8_t i=0; i<4; i++) { |
7 | tmp = 10 * tmp + (bcd[i] >> 4); |
8 | tmp = 10 * tmp + (bcd[i] & 0x0f); |
9 | }
|
10 | |
11 | tmp = 10 * tmp + (bcd[4] >> 4); |
12 | |
13 | if (tmp > 0x33333333) // 2**33 / 10 |
14 | bin[0] = 0x02; |
15 | else if (tmp > 0x19999999) // 2**32 / 10 |
16 | bin[0] = 0x01; |
17 | else
|
18 | bin[0] = 0x00; |
19 | |
20 | tmp = 10 * tmp + (bcd[4] & 0x0f); |
21 | |
22 | if (tmp < (bcd[4] & 0x0f)) |
23 | ++bin[0]; |
24 | |
25 | for (uint8_t i=4; i; i--) { |
26 | bin[i] = (uint8_t)tmp; |
27 | tmp >>= 8; |
28 | }
|
29 | }
|
30 | |
31 | int main(void) { |
32 | uint8_t bcd1[5] = { 0x99, 0x99, 0x99, 0x99, 0x99 }; |
33 | uint8_t bcd2[5] = { 0x79, 0x52, 0x63, 0x29, 0x52 }; |
34 | uint8_t bin[5]; |
35 | |
36 | printf("dec: %02X%02X%02X%02X%02X\n", bcd1[0], bcd1[1], bcd1[2], bcd1[3], bcd1[4]); |
37 | bcd2bin(bcd1, bin); |
38 | printf("hex: %02X%02X%02X%02X%02X\n", bin[0], bin[1], bin[2], bin[3], bin[4]); |
39 | printf("\n"); |
40 | printf("dec: %02X%02X%02X%02X%02X\n", bcd2[0], bcd2[1], bcd2[2], bcd2[3], bcd2[4]); |
41 | bcd2bin(bcd2, bin); |
42 | printf("hex: %02X%02X%02X%02X%02X\n", bin[0], bin[1], bin[2], bin[3], bin[4]); |
43 | }
|
Ausgabe:
1 | dec: 9999999999 |
2 | hex: 02540BE3FF |
3 | |
4 | dec: 7952632952 |
5 | hex: 01DA038C78 |
Ich bin davon ausgegangen, dass die Bytes sowohl in der BCD- als auch in der Binärdarstellung in der Big-Endian-Reihenfolge in den jeweiligen Arrays abgelegt werden. Falls Little-Endian gewünscht ist, müssen lediglich die ARray-Indizes angepasst werden. Die niederwertigen 4 Bytes des Ergebnisses werden berechnet, indem eine 32-Bit-Variable (tmp) abwechselnd mit 10 multipliziert und dann eine Dezimalziffer hinzuaddiert wird. Das höchstwertige Byte des Ergebnisses (bin[0]) kann nur die Werte 0, 1 oder 2 annehmen. Der passende Wert wird per Fallunterscheidung bestimmt. Schließlich werden die 4 Bytes von tmp in das Ergebnis-Array (bin[1..4]) übertragen.
:
Bearbeitet durch Moderator
In ganz primitiv könnte das etwa so aussehen. Erstmal ein neues 5 Byte Array anlegen und mit 0 initialisieren. Dann das Array mit den gepackten BCD Werten bitweise nach links schieben. Für jedes gesetzte Bit das hexadezimale Äquivalent auf das neue Array addieren. Bit 40 -> 1 DC D6 50 00 Bit 39 -> EE 6B 28 00 Bit 38 -> 77 35 94 00 Bit 37 -> 3B 9A CA 00 Bit 36 -> 2F AF 08 00 Bit 35 -> 17 D7 84 00 usw. bis Bit 6 -> 14 Bit 5 -> A Bit 4 -> 8 Bit 3 -> 4 Bit 2 -> 2 Bit 1 -> 1
Bereits um 13:13 hat Dir jemand einen einfachen Lösungsvorschlag gemacht, den Du nichtmal ignoriert hast. Irgendwie kommt mir da die Frage in den Sinn: Suchst Du noch (eine Lösung), oder trollst Du schon? Nachdem Dein Compiler - der ja gesetzt ist - nicht mit Ganzzahlen größer uint32, also 2^32-1 oder gut 4 Milliarden rechnen kann, Du allerdings mit Ganzzahlen in der 99 Milliarden rechnen mußt, wirst Du schlicht und einfach nicht drum rum kommen Dir zumindest die eine oder andere Rechenoperation händisch zu Fuß auszuprogrammieren (oder von irgendwo zusammen copy/pasten). Bei Helmuths Vorschlag wäre das die Subtraktion um von Deinem 10stelligen Eingabewert eine 9-stellige Konstante abzuziehen. Wobei die Subtraktion (oder Addition) eben den Vorteil haben, daß man problemlos erst die hinteren 6, 7 oder 8 Stellen beider Zahlen nehmen und voneinander subtrahieren kann und anschließend die übrigen Stellen ebenso einfach subtrahieren kann als wärens 2, 3 oder 4 stellige Dezimalganzzahlen. Bloß einen allfälligen Übertrag von der ersten Subtraktion muß man hier noch mitberücksichtigen.
Es reicht auch, die höchstwertige BCD-Stelle abzutrennen, die zum 32-Bit-Überlauf führen kann. Diese mit etwas Kleinerem ausmultiplizieren (z. B. 1e9/256) und stellenrichtig mit Überlauferkennung addieren.
1 | unsigned char bcd[5] = {0x99, 0x99, 0x99, 0x99, 0x99}; /* from card reader */; |
2 | unsigned long hexhigh, hexlow, hexlow1; |
3 | unsigned char hex[5]; /* result */ |
4 | |
5 | hexhigh = (bcd[0] >> 4) * 3906250; /* 1e9 >> 8 */ |
6 | hexlow1 = (bcd[0] & 15) * 100000000 |
7 | + (bcd[1] >> 4) * 10000000 |
8 | + (bcd[1] & 15) * 1000000 |
9 | + (bcd[2] >> 4) * 100000 |
10 | + (bcd[2] & 15) * 10000 |
11 | + (bcd[3] >> 4) * 1000 |
12 | + (bcd[3] & 15) * 100 |
13 | + (bcd[4] >> 4) * 10 |
14 | + (bcd[4] & 15) * 1; |
15 | hexlow = hexlow1 + (hexhigh << 8); |
16 | |
17 | if (hexlow < hexlow1) /* add carry */ |
18 | hexhigh += 1 << 24; |
19 | |
20 | hex[0] = hexhigh >> 24; |
21 | hex[1] = hexlow >> 24; |
22 | hex[2] = hexlow >> 16; |
23 | hex[3] = hexlow >> 8; |
24 | hex[4] = hexlow; |
25 | printf ("%02x.%02x.%02x.%02x.%02x", hex[0], hex[1], hex[2], hex[3], hex[4]); |
02.54.0b.e3.ff
:
Bearbeitet durch User
Roger P. schrieb: > Ich lese diese 5 byte aus der Karte und die sind per Definition eine > Dezimalzahl! Der war aber schon arg speziell, der das in völliger Ignoranz der bestehenden Datenformate genau so definiert hat, dass ein wenig mehr als 33 Bit für diese Information benötigt wird. Hast du mal einen Link auf diese fiese Spec? Roger P. schrieb: > Also habe ich ab einer dezimalen Kartennummer >00 99 99 99 99 ein > Problem bei der Umwandlung in Hexadezimale darstellung. Mit allerhöchster Wahrscheinlichkeit deshalb, weil der Erfinder nich dran gedacht hat, dass das irgendwer mal in eine Zahl umwandeln will. Roger P. schrieb: > jedes Byte "geht" dezimal von 0-99 zu definieren. Weißt du inzwischen, was BCD ist? > Diese Nummer ist eben in 5 Byte abgelegt. Und nochmal meine Frage von vorhin (auch ein paar andere hatten das gefragt): was willst du mit dieser Nummer als "Zahl" anschließend machen? Sie durch Pi teilen oder mit der Uhrzeit multiplizieren oder das Alter dws Besitzers abziehen oder sonst eine Rechnung? Oder willst du sie nur speichern und/oder vergleichen?
:
Bearbeitet durch Moderator
Hallo Jörg das ist nicht spezial. Im Chipkarten Welt ( Zutritt Zeiterfassung) ist das durchausüblich das große Hersteller das so machen. Ich habe schon krassere Fälle erlegt. Hintergrund: Der Leser muss zwei verschiedenen Medien lesen. Das eine Chipkartenmedium liefert Hex und das ander Dezimal. (Legic) Das ist alles. Weiterverarbeitet und übermittelt muss im gleichen bestehenden Format. Das sind eben die Randbedingungen. Und ja - wir hatten auch schon Kartennummer in diesem BCD Format wo das high nibble 0 ist. 09|09|09 = Kartennummer 999 - Platzverschwendung hin oder her. Roger
:
Bearbeitet durch User
Roger P. schrieb: > Und ja - wir hatten auch schon Kartennummer in diesem BCD Format wo das > high nibble 0 ist. > 09|09|09 = Kartennummer 999 Das ist nicht BCD. Sondern einfach 1 Byte pto Zehnerstelle. Seis drum... > Weiterverarbeitet und übermittelt muss im gleichen bestehenden Format. Diese 5 BCD Bytes werden also lediglich zu einem bestehenden Format "weiterverarbeitet". Und damit kommen wir dem Kern der Sache allmählich ganz langsam näher: wie sieht dieses "gleiche bestehende Format" aus?
Hallo Jörg,
>> wie sieht dieses "gleiche bestehende Format" aus?
Also es werden Kartendaten Daten incl der Kartennummer an ein Zentrales
System (LAN -seriell) übertragen. Dort gibt es ein Datenfeld von 5 Byte
in dem die Kartennummer definiert MSL-LSB in hex Format übermittelt
wird.
Ja was ist BCD BCD ist ein Nibble von 4 Bit wo die Pseudotetraden
nicht vorkommen....
das mit 09|09|09 = Kartennummer 999 ist eine Definitionssache. Ich haben
schon häufig erlebt das so programmiert ist.
Auch in ASCII Darstellung 39h|37h|32h = "972"
Roger
:
Bearbeitet durch User
Roger P. schrieb: > Also habe ich ab einer dezimalen Kartennummer >00 99 99 99 99 ein > Problem bei der Umwandlung in Hexadezimale darstellung. Nein, erst ab 4.294.967.296
Lothar M. schrieb: > Das ist nicht BCD. Sondern einfach 1 Byte pto Zehnerstelle. Seis drum... Hmm, ich denke schon:
1 | 11[dez] = 0x01 0x01[unpacked BCD] |
2 | 11[dez] = 0x11[packed BCD] |
Leider hat Roger nicht wirklich was zu seiner Formatierung geschrieben. Seine Angabe "99" lässt sich unterschiedlich Interpretieren:
1 | 99 = 99[dez] = 0x63[hex] |
2 | 99 = 0x99[packed BCD] = 0x99[hex] |
Je nachdem sieht die optimale Routine halt anders aus.
Rainer W. schrieb: > Nein, erst ab 4.294.967.296 Oder in Rogers Schreibweise: 42|94|96|72|96. Andreas M. schrieb: > Leider hat Roger nicht wirklich was zu seiner Formatierung geschrieben. Probieren wir das mal als Hörspiel. Es gibt 2 Teilnehmer: L und R L: Warum gibst du da nicht einfach die 5 Bytes der Kartennummer weiter? R: Weil es bereits ein Übertragungsformat definiert ist und das verwendet werden muss! L: Ah, ok, und was wird da weiter übertragen? Was soll aus den 5 Bytes der Kartennummer gemacht werden? Müssen die für die Übertragung irgendwie umgewandelt werden? R: ...(erklärt, in welches Format er die 5 Bytes für die weitere Übertragung umwandeln muss)
:
Bearbeitet durch Moderator
Roger P. schrieb: > Ich weis nicht was daran nicht richtig beschrieben ist. Ganz einfach, eine Dezimalzahl wird nicht so im Speicher abgelegt, wie du es beschreibst, deine Aufgabestellung ist also widersprüchlich. Sie liegt binär im Speicher. Das was du meinst ist Packed BCD, das wurde dir auch schon mehrfach gesagt. Da du aber nicht zu verstehen scheinst was man dir schreibt und nur blind durchziehst was du denkst, ohne auf die vielen anderen Hinweise und Lösungsansätze einzugehen, kommst du nicht voran. Ändere mal was an deinem Ton und fange endlich an auf die Hinweise hier einzugehen, bisher hast du dich nur mit deinem Hass auf Harald und alle die die nicht direkt dein Problem verstehen, konzentriert und noch nicht ein Wort zu den vielen guten Hinweisen gesagt, beginnend ungefähr mit dem von Peda. Eine Lösung muss man sich immer erarbeiten, zu erwarten dass einem einer direkt auf eine Anfrage eine 100% Lösung als Antwort gibt, gibt es nicht! Selbst wenn die Anfrage eindeutig, komplett und völlig zweifelsfrei ein Problem beschreibt, wozu deine und 99,9% aller Anfragen NICHT zählen. Es bleibt nur, mit den Helfenden zusammen zu arbeiten, was du definitiv nicht machst, warum auch immer. Ich habe es selten jemand so arrogantes wie dich erlebt...
:
Bearbeitet durch User
Martin S. schrieb: > Es bleibt nur, mit den Helfenden zusammen zu arbeiten, was du definitiv > nicht machst, warum auch immer. Das "warum" ist mir klar: für Roger sprechen wir eine Art Fremdsprache. Er versteht nicht, was wir sagen. Er will sich aber auch nicht helfen lassen und erklärt nicht, was er denn eigentlich machen muss. Sonder er beharrt nur darauf, dass es so gemacht werden muss wie "bisher", ohne zu sagen, was das denn ist, was da "bisher" gemacht wurde. > Ich habe es selten jemand so arrogantes wie dich erlebt... Das Verhalten von Roger ist nicht arrogant, sondern es ist ein Indiz dafür, dass er sein "Problem" nicht auseichend überblickt. Und dann geht er auch schon gleich in Verteidigungsmodus. Roger P. schrieb: > Der Algorithmus beginnt mit Zahl / 16 Welcher "Algorithmus"? Was kommt nach Anwendung dieses "Algorithmus" heraus? > Der Algorithmus beginnt mit Zahl / 16 Das ist eigentlich gut, denn wenn er das tut, dann wird aus der für einen vorzeichenlosen 32-Bit Integer um den Faktor 2,3 zu großen Zahl 9999999999 die Zahl 0999999999, die dann als 0x3B9AC9FF wieder völlig problemlos in einen 32-Bit Integer passt.
Roger P. schrieb: > ich lese von einer Chipkarte 5 Byte und stecke diese in ein 5Byte Array. > Kann die nicht in eine Uint32 stecken. Einfach mit winzip zippen ;-) Warum konnten eigentlich die 4Bit CPUs in Taschenrechner mit Zahlen größer 15 Rechnen?
:
Bearbeitet durch User
Roger P. schrieb: > Diese 5 Byte sind von 0 bis 9999999999 > Kann die nicht in eine Uint32 stecken. Ja, ist ja logisch, weil log2(dez9999999999) = 33,22 ist und deshalb 34 Bits für diese Dezimalzahl 9999999999 nötig sind. Also kann schon prinzipiell und mathematisch kein wie auch immer gearteter "Algorithmus" diese Dezimalzahl 9999999999 verlustfrei in 32 Bit packen. Das musst du jetzt entweder einfach nachvollziehen oder einfach glauben. Denn dann kannst du den nächsten Schritt zur Lösung gehen: Was soll mit diesem Integerwert hinterher gemacht werden? Dient er (wie z.B. für Legic-Zeitbuchungs- oder Zutrittskarten üblich) nur zur Erkennung und Unterscheidung einer einzelnen Karte aus 500 anderen Karten, damit dem richtigen Mitarbeiter die Zeit zugebucht oder der Zutritt gewährt wird? Dann verlagert sich die Sache nämlich ganz schnell in Richtung "Wahrscheinlichkeiten" und wird mit ein wenig Nachdenken genauso schnell ganz einfach...
:
Bearbeitet durch Moderator
Obelix X. schrieb: > Warum konnten eigentlich die 4Bit CPUs in Taschenrechner mit Zahlen > größer 15 Rechnen? Gibt's nicht sogar einen (von HP?), der ein langes 1-bit-breites Schieberegister ist, auch das interne Programm? Lothar M. schrieb: > Dann verlagert sich die Sache nämlich ganz schnell in Richtung > "Wahrscheinlichkeiten" und wird mit ein wenig Nachdenken genauso schnell > ganz einfach... Wat? Klär mich bitte auf...
Jens M. schrieb: > Lothar M. schrieb: >> Dann verlagert sich die Sache nämlich ganz schnell in Richtung >> "Wahrscheinlichkeiten" und wird mit ein wenig Nachdenken genauso schnell >> ganz einfach... > > Wat? Klär mich bitte auf... Das ist doch ganz simpel: aus den 40 Bit der Quelle (effektiv allerdings nur mit einem Informationsgehalt von 33,22 Bit) generiert man einen 32 Bit Hashwert. Mit der Wahrscheinlichkeitsrechnung kann man dann aufzeigen, dass eine Kollision extrem unwahrscheinlich ist. Jedenfalls, wenn der Hash-Algorithmus gut ist.
Man muss unterscheiden zwischen den Darstellungen einer Zahl und der Abbildung im Speicher. Roger möchte die zehnstellige Dezimalzahl die als packed BCD in fünf Bytes im Speicher liegt gern als eine große binäre in fünf Bytes (dann 34 bit) im Speicher haben. Wie er das lösen kann, wurde Ihm hier mehrfach genannt: Beitrag "Re: Hilfe - Umrechung 5 Byte! Array Dezimal => Hex." Will er aber nicht annehmen oder verstehen...das ist aber ein anderes Problem. Wer nicht will der hat schon, so ist es nunmal.
:
Bearbeitet durch User
Hallo zusammen zunnächst bedanke ich mich mal bei allen die mitgeholfen haben. Sollte ich arrogant rübergekommen sein so entschuldige ich mich ... >> Zu Lothar M. Was soll mit diesem Integerwert hinterher gemacht werden? Dient er (wie z.B. für Legic-Zeitbuchungs- oder Zutrittskarten üblich) nur zur Erkennung und Unterscheidung einer einzelnen Karte aus 500 anderen Karten, damit dem richtigen Mitarbeiter die Zeit zugebucht oder der Zutritt gewährt wird? >> das sind Chipkarten die u.a in großen Konzernen/ Unternehmen eingesetzt werden. Also meist mehrere tausend Karten. Die Kartennummer sind zum Teil Offset, damit man diese den einzelnen Gruppen/Standorten zuordnen kann. 0100000000 - 0199999999 Standort A 0200000000 - 0299999999 Standort B usw Roger
Lothar M. schrieb: > Das Verhalten von Roger ist nicht arrogant, sondern es ist ein Indiz > dafür, dass er sein "Problem" nicht auseichend überblickt. Was sich aber völlig mit der anscheinend "professionellen" Anwendung widerspricht. Wenn da jemand den Azubi an die Aufgabe gesetzt hat, dann soll der Ausbilder gefälligst seinen Job machen. Wenns kein Azubi ist, hat die Firma ein Problem. Allerdings hat der TO mal wieder nachgewiesen, daß das Forum wie eine KI funktioniert. Wenn man nur lange genug am Prompt rumbastelt, spuckt das schließlich doch die Lösung aus. Oliver
:
Bearbeitet durch User
>>Oliver S
Jetzt reg dich mal ab. Du bist ja nicht zu ertragen!
:
Bearbeitet durch User
Peter D. schrieb: > Und dann in einer Schleife: 1. Byte BCD * 2 , d.h. addieren mit sich > selber mit Dezimalkorrektur. Dann das 2. Byte + Übertrag vom ersten Byte > usw. bis zum 5 Byte. Der Übertrag vom 5. Byte wird dann in das Zielarray > von rechts geschoben. Und das ganze in einer Schleife 40*. Kann es sein, dass du dich da etwas vertan hast? Vielleicht habe ich dich aber auch nur falsch verstanden. So habe ich dich verstanden: 40-mal BCD-Wert verdoppeln und Übertrag jeweils von rechts in das Ergebnis schieben. Richtig wäre aber: 40-mal BCD-Wert halbieren und Rest jeweils von links in das Ergebnis schieben. Also genau andersherum. Wird das Halbieren als Rechts-Shift mit Dezimalkorrektur implementiert, entspricht das Verfahren exakt dem Reverse-Double-Dabble-Algorithmus.
Roger P. schrieb: > Also meist mehrere tausend Karten. Die Wahrscheinlichkeit einer "Doppelbelegung" ist gering: wenn man die 4,2 Milliarden Möglichkeiten des Integers gegen 4000 Karten rechnet, dann kommt es in 1 von 1 Million Fällen zur Überschneidung. Da würde ich ganz ruhig schlafen. > Die Kartennummer sind zum Teil Offset, damit man diese den einzelnen > Gruppen/Standorten zuordnen kann. > 0100000000 - 0199999999 Standort A > 0200000000 - 0299999999 Standort B usw 1. Fail by Design. Dieser Ansatz ist kurde, weil ja pro Standort sicher niemals auch nur annähernd hundert Millionen Karten kursieren. 2. Halb so wild, denn so lange es nicht mehr als 41 Standorte gibt, passt das Ergebnis locker in den 32-Bit Integer, denn 4199999999 ist kleiner als 4294967295. Aber nochmal, wenn du 10 Milliarden Karten unterscheiden willst, dann reicht ein 32-Bit Integer garatiert nicht mehr aus.
Assemblertechnisch hat man es auch immer mit Formatfragen zu tun (Stichwort 0a0d). Wenn eine Zahl zu groß ist, kann man sie zumindest durch 2 teilen, durch 4, durch 8, durch 16, durch 32 oder durch 64 usw. Dann übersetzen, und hinterher wieder multiplizieren. 25/16 ist z.B. 19 -> 0001 1001 jetzt müsste man 2x nach links shiften bzw. rotieren, um auf 100/16 zu kommen. Handschriftliches Dividieren geht ja auch mit größeren Zahlen und Portionsweise. Trickreiche Multiplikation gibt es auch noch, und es ist nützlich, sie zu kennen: https://de.wikipedia.org/wiki/Karazuba-Algorithmus
Wann kommt von dir endlich eine Rückmeldung zu den Vorschlägen hier? Beitrag "Re: Hilfe - Umrechung 5 Byte! Array Dezimal => Hex." So vehement wie du sie allesamt ignorierst und nach wie vor nur auf die Pöbelei eingehst scheinst du nicht wirklich an einer Lösung interessiert zu sein...oder du verstehst die Antworten nicht!?
:
Bearbeitet durch User
>> Lothar Die Wahrscheinlichkeit einer "Doppelbelegung" ist gering: wenn man die 4,2 Milliarden Möglichkeiten des Integers gegen 4000 Karten rechnet, dann kommt es in 1 von 1 Million Fällen zur Überschneidung. Da würde ich ganz ruhig schlafen. Ja - aber die Vorgaben werden meist nicht von mir sondern von den Karteninhabern (Zutritt Dorna Kaba, Interfex, Legic, etc) und den Kunden gemacht. >>von Martin S >>Wann kommt von dir endlich eine Rückmeldung zu den Vorschlägen hier? Warum bist du so ungeduldig. Von dir kam kein einziger Vorschlag. Nur mecker &Co. das kann jeder schnell nachverfogen der hier durchscrollt. Roger
:
Bearbeitet durch User
Martin S. schrieb: > Roger möchte die zehnstellige Dezimalzahl die als packed BCD in fünf > Bytes im Speicher liegt gern als eine große binäre in fünf Bytes (dann > 34 bit) im Speicher haben. Da sind aber noch immer diese Fragen offen: 1. ob das tatsächlich so ist 2. ob und warum das nötig ist Denn da taucht immer wieder irgendwas "Bestehendes" auf: Roger P. schrieb: >>>> müssen ein äteres bestehendes System anpassen... Roger P. schrieb: >>>> Weiterverarbeitet und übermittelt muss im gleichen bestehenden Format. Und der TO Roger sollte nach zig Nachfragen endlich mal sagen, wie denn dieses "bestehende" Format aussieht, in das die übergroße Zahl gewandelt werden soll. Wir fragen da ja nicht zum ewigen Zeitvertreib, sondern weil es für die Problemlösung nötig ist. Roger P. schrieb: > Ja - aber die Vorgaben werden meist nicht von mir sondern von den > Karteninhabern (Zutritt Dorna Kaba, Interfex, Legic, etc) und den Kunden > gemacht. Du schwurbelst herum. Um welche "Vorgaben" geht es denn? Wie sieht das "bestehende" Format aus?
:
Bearbeitet durch Moderator
Hallo Lothar, Wenn man bestehende Karten eines Unternehmens nutzen will umd damit eine eine andere Anwendung zusatzlich zu realisieren sind die Vorgaben oft so. Man kann nicht die Karten austauschen oder umprogrammieren. Oft sind es nur ID medien (125Khz) oder man bekommt nicht die Berechtigung eine weite Applikation auf die Karte aufzubringen. (DESFire, Legic). Dazu noch der Logistische Aufwand. das ist bei kleinen Unternehmen noch teils realsierbar. Bei größeren nicht. Also muss man das nehmen was da ist. Und wenn die Kartennummer und andere Daten nun mal so oder so drauf sind muss man das nehmen. Roger
Hallo Lothar Beispiel: DESFire Kartennummer im Interflex Zutritt Application ID 0x7080F4 [0000] 01 21 00 23 00 00 00 07 85 52 71 28 1F 00 52 A5 [0010] FE 15 41 07 10 90 00 FF CF A0 30 00 00 00 00 00 das ist z.B eine Kartennummer 0785527128 (Hex, binär) ist die Kartennummer aufgedruckt 785527128 (dezimal) enspricht was der Karten in 002ED23158 hexadezimal im gleichen 5Byte Array entspricht. Roger
:
Bearbeitet durch User
Dieser Internet-Rechner schafft dies https://www.mathwarehouse.com/solved-problems/conversions/convert-999999-from-decimal-to-binary A) Einfach die 10 Stück 9-er eingeben, binär oder hdxadezimal als Ausgabewert, stimmt mit dem von TE auch bereits ermitteltem Wert überein. B) Mit dem Rechner kann man weitere 2 oder 4 Stellen, dann 14, wahrscheinlich noch mehr, auch umrechnen. Also da mal den Quellcode erforschen ...
Und welche Operationen müssen dann mit dieser Zahl gemacht werden? Zur Not muss man diese Operationen halt (von Hand) ausprogrammieren. Man könnte auch zu einer BCD Zahl konvertieren, dafür sollte es ausreichend Beispiele für Operationen geben.
Roger P. schrieb: > das ist z.B eine Kartennummer 0785527128 (Hex, binär) ist die > Kartennummer aufgedruckt 785527128 (dezimal) enspricht > was der Karten in 002ED23158 hexadezimal im gleichen 5Byte Array > entspricht. Was ich mich frage: warum wandelst du die Nummer dann überhaupt um, wenn sie vorher 5 Byte gebraucht hat und nachher wieder die selben 5 Byte braucht? Es ist ja keine Information in dieser Nummer, die man mit einer Rechnung extrahieren könnte. Die alleinige Information ist doch letztlich die Nummer selber.
Hallo Lothar, da ist ein Kartenlesegerät. Das liest z.B einmal eine Hitag Karte mit der auch in 5 Byte Hex gespeicherten Kartennummer AABBCCDDEE und überträgt auch AABBCCDDEE weil das Zielsystem die Kartennummer 5Byte hex interpretiert. Nun soll der gleiche Leser auch eine andere Karte wo die Kartennummer 9999999999 = 02540BE3FF hex drin ist auch die 02540BE3FF als Kartennummer übertragen. das Zielsystem rechnet bzw. arbeitet immer mit dieser Konvention. Daran ist nichts zu ändern. Es gibt keine Möglichkeit mitzuteilen wie die Kartennummer formatiert ist. Roger
Roger P. schrieb: > Warum bist du so ungeduldig. Okay, du hast anscheinend Langeweile, oder bist gar nicht an einer Lösung interessiert... Roger P. schrieb: > Von dir kam kein einziger Vorschlag. Ne, warum auch, du gehst ja eh nicht darauf ein ... https://www.martin-ruetter-live.de/der-will-nur-spielen
Roger P. schrieb: > eine Hitag Karte ... AABBCCDDEE weil das Zielsystem > ... > 02540BE3FF als Kartennummer übertragen. das Zielsystem Das sind also unterschiedliche Zielsysteme, oder wie? Und: kann eine Hitag-Karte auch mal 99 99 99 99 99 enthalten? Falls ja, was soll dann passieren? Soll 9999999999 übertragen werden oder 02540BE3FF? > Nun soll der gleiche Leser auch eine andere Karte wo die Kartennummer > 9999999999 = 02540BE3FF hex drin ist Ich dachte, in der einen Karte ist 99 99 99 99 99 drin, so wie in der anderen Karte AA BB CC DD EE drin ist. Und wenn das eine Mal AABBCCDDEE übertragen wird, dann kann man das andere Mal 9999999999 übertragen. > auch die 02540BE3FF als Kartennummer übertragen. Dann nimm die Lösung von Yalu. Martin S. schrieb: > Roger P. schrieb: >> Warum bist du so ungeduldig. > Okay, du hast anscheinend Langeweile, oder bist gar nicht an einer > Lösung interessiert... Muss nicht sein, aber Roger ist sicher kein guter Projektmanager.
:
Bearbeitet durch Moderator
Hallo Lothar,
Nein, das gleiche Zielsystem. Nur der Kartenleser arbeitet mit
verschiedene Karten. Das ist so wenn eine Kartenumstellung von alt auf
neu erfolgt. So ein Übergang ist schleichend und es muss mit diesen 2
Formaten gehen.
Es gibt keine "doppelten" Kartennummern. Das wird per Offset festgelegt.
>>Projektmanager
Das hat so nicht mit Projektmanagement zu tun. Sondern nur eine
technische / software Lösung.
Roger
:
Bearbeitet durch User
Roger P. schrieb: > Nun soll der gleiche Leser auch eine andere Karte wo die Kartennummer > 9999999999 = 02540BE3FF hex Wenn das System mit 10-stelligen Hex-Zahlen umgehen kann, könntest du ihm doch einfach verschweigen, dass deine Karten keine Hex-Daten, sondern BCD enthalten. Oder werden beide Systeme parallel genutzt, so dass es zu Überschneidungen kommen kann. Egal, was du mit den Daten rummachst - weniger als 5 Byte werden es nicht, ohne sich mit Wahrscheinlichkeiten zu beschäftigen, es sei denn, es kann ausgeschlossen werden, dass Standorte mit einer Standort-/Gruppennummer über 41 auftreten.
Innerhalb von einem Tag sollte ein IT-ler das selbständig hinbekommen. Andere sitzen ein Tag vor dem PC und hacken etwas in ein Forum anstatt mit der Arbeit anzufangen. By the way, sucht ihr noch Mitarbeiter?
Roger P. schrieb: > Das hat so nicht mit Projektmanagement zu tun. Doch, das hat es. Dein wirklich simples und kleines "Projekt" ist es hier, die Anforderungen zu erfüllen. Und dafür musst du erst mal die Anforderungen verstehen und klären. > Das ist so wenn eine Kartenumstellung von alt auf neu erfolgt. Die nächste Salamischeibe. > So ein Übergang ist schleichend und es muss mit diesen 2 Formaten gehen. wie gesagt: ich kann hier prinzipiell keine 2 "Formate" erkennen. Beide Male werden 5 Byte übertragen, die ausser der Kartennummer keine Information tragen. Also muss man nur dafür sorgen, dass es keine gleichen Kartennummern gibt.
Lothar, Man muss die Rahmenbedingung akzeptieren Du würdest beides " gleich" übertragen und das Zielsystem soll unterschieden und umrechnen. Zwar ein Lösungsansatz - der aber nun nicht realsiert werden kann. Ich habe einfach gefragt eine 5 Byte Zahl Array umgerechnet in Hex werden kann wenn man nur uint32 hat...dazu muss man gar nichts weiter kennen. Das hätte so in einer Klausaufgabe stehen können -ich hatte 0 Punkte bekommen Aber viele andere hier auch. Es gab hier auch von 2-3 Leuten konkrete Lösungen. Der "Rest" hat sich an drumherum aufgehalten und ist zum teil auch ausfallend geworden. Aber so ist man das ja leider hier im Forum. (damit bist nicht du Lothar gemeint) Roger
:
Bearbeitet durch User
Wie viel zahlt dein Unternehmen mir den wenn ich das für dich programmieren?
Lieber >>Obelix X >>Einfach mit winzip zippen ;-) >>Wie viel zahlt dein Unternehmen mir den wenn ich das für dich >>programmieren? Las gut sein! Roger
Roger P. schrieb: > DESFire Kartennummer im Interflex Zutritt Application ID 0x7080F4 > [0000] 01 21 00 23 00 00 00 07 85 52 71 28 1F 00 52 A5 > [0010] FE 15 41 07 10 90 00 FF CF A0 30 00 00 00 00 00 > > das ist z.B eine Kartennummer 0785527128 (Hex, binär) ist die Ich gehe davon aus [0000], [0010] einfach die Adresse in Hexadezimal ist, so wie man es von der Anzeige einem beliebigen HexEditor, etc kennt. Dann ist das nicht "hex binär" sondern "packed BCD" Format. Roger P. schrieb: > Kartennummer aufgedruckt 785527128 (dezimal) enspricht > was der Karten in 002ED23158 hexadezimal im gleichen 5Byte Array > entspricht. Was nichts weiter heist das du eine Zahl im Format "Packed BCD" (5 Byte/10 Stellen, Big-Endian) ins Binärformat umwandeln willst, (5 Byte/40 Bit,Big-Endian) Du muss mal schauen, dass Du die Fachbegriffe nicht vermischst, sonst versteht dich kein Mensch. Eine "Hexadezimalzahl" gibt es im Computer nicht. Entweder ists Binär oder es ist ein String, der die Hexadezimaldarstellung der Zahl enthält. (Der hätte in diesem Fall aber nicht 5 sondern 10 Byte) Du brauchst also einfach nur einen Packed BCD -> Binär Konvertieralgorithmus. Ich würds per "Schriftliche Division /256" umsetzen.
Roger P. schrieb: > Las gut sein! War nur ein gut gemeintes Angebot, dann hättest du den Code in 10min und müsstest dir den Thread hier nicht noch einen Tag antun.
Roger P. schrieb: > Ich habe einfach gefragt eine 5 Byte Zahl Array umgerechnet in Hex > werden kann wenn man nur uint32 hat...dazu muss man gar nichts weiter > kennen. Was auch immer dieses Kauderwelsch bedeuten soll - solange für dein 5 Byte der volle Zahlenraum 10-stelliger Dezimalzahlen zulässig ist, lässt sich das auf Grund des Informationsgehaltes nicht verlustfrei auf 32 Bit abbilden. Mache dich mit den Grundlagen vertraut und teile uns die Randbedingungen vollständig mit. Ohne Einschränkungen funktioniert es nicht - egal wie du dich quer stellst.
Rainer W. schrieb: > lässt > sich das auf Grund des Informationsgehaltes nicht verlustfrei auf 32 Bit > abbilden. Ich habe ihn schon so verstanden, dass es 5 Byte Input hat (9.999.999.999 = 0x99 0x99 0x99 0x99 0x99) und 5 Byte Output ( 0x02 0x54 0x0B 0xE3 0xFF)
:
Bearbeitet durch User
Obelix X. schrieb: > War nur ein gut gemeintes Angebot, dann hättest du den Code in 10min und > müsstest dir den Thread hier nicht noch einen Tag antun. Was nutzt ihm noch ein Code neben den hier im Thread schon vorhandenen? Die hier sind sogar in C, und tatsächlich direkt nutzbar. Nur ist seine Trolligkeit damit ja augenscheinlich immer noch überfordert. Oliver
Oliver S. schrieb: > Was nutzt ihm noch ein Code neben den hier im Thread schon vorhandenen? > Die hier sind sogar in C, und tatsächlich direkt nutzbar. Nur ist seine > Trolligkeit damit ja augenscheinlich immer noch überfordert. Ich habe nochmal hochgescrollt ... Oha, da habe ich wohl einen Beitrag übersehen ;-). Dann wird es wohl hier nichts für mich mit dem abkassieren ;-).
>> Rainer W >>Was auch immer dieses Kauderwelsch bedeuten soll - solange für dein 5 >>Byte der volle Zahlenraum 10-stelliger Dezimalzahlen zulässig ist, lässt >>sich das auf Grund des Informationsgehaltes nicht verlustfrei auf 32 Bit >>abbilden. Meine Fresse - Zu letzten mal erklärt und bitte vor posten lesen und denken In C Keil C51 - es gibt nur Uint32 variabeln Ein 5 Byte Array als Ganzzahl => in 5 Byte Array Ganzzahl hex umrechnen Es geht mit einen besonderen Rechenablauf schon. Der heißt wie ich nun erfahren habe - Reverse double dabble. Der wird in kürze von mir getestet. und Obelix X und Oliver S Ihr hab ausser Trollen absolut gar nix Inhaltliches beigetragen. Wenn ein anderer die Lösung gepostet hat ist es einfach die Klappe aufzutun! Roger
:
Bearbeitet durch User
Kay-Uwe R. schrieb: > if (hexlow < hexlow1) /* add carry */ > hexhigh += 1 << 24; Da könnte einem eine nicht passende endianess Ärger machen. Oliver
Roger P. schrieb: > Es geht mit einen besonderen Rechenablauf schon. Der heißt wie ich nun > erfahren habe - Reverse double dabble. > Der wird in kürze von mir getestet. Ich wiederhole mich da vorsorglich mal: Oliver S. schrieb: > Da könnte einem eine nicht passende endianess Ärger machen. Wenn du weisst, was du tust, ist das kein großes Problem. Wenn du das Wort endianess dagegen noch nie gehört hast, solltest du dir das vorher mal anschauen. Warum nimmst du nicht einfach einen der hier schon geposteten Codes? Oliver
Roger P. schrieb: > Wenn ein anderer die Lösung gepostet hat ist es einfach die Klappe > aufzutun! Die waren dir ja wohl nicht gut genug. Deswegen habe ich dir halt meine Hilfe angeboten, nur halt nicht kostenlos. Für ein Großunternehmen sollte das ja keine Problem darstellen.
Roger P. schrieb: > Also muss man das nehmen was da ist. Und wenn die Kartennummer und > andere Daten nun mal so oder so drauf sind muss man das nehmen. Also sorry, Roger, aber irgend wie passen Deine Antworten nicht zu den Fragen. "Ist eben so", "da kann man nichts dran ändern" etc. Solche Antworten haben doch nichts mit den Fragen zu tun, die Dir gestellt werden. Was ist nur mit Dir los? ciao Marci
Roger P. schrieb: > Meine Fresse Auch wegen solcher Reaktionen bist du besser kein Projektleiter... ;-) Aber ich glaube sowieso, das Thema an sich ist jetzt durch. Jetzt dauert es erst mal ein paar Tage, bis BCD-Zahlen und Double Daddle verstanden sind und der zugehörige umgekehrte Double Daddle umgesetzt ist. Bis dahin mache ich den Laden hier dicht.