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ß"....?
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ß"....?
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.
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.
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.
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. ;-)
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.
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)
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?
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?
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."
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.
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)
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...
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".
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.
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.
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.
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?
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.
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.
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.
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.
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.
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.
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.
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:
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...
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.
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.
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.
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
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.
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.
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.
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?
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.
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?
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.
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)
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...
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.
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.
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...
Dann verlagert sich die Sache nämlich ganz schnell in Richtung
"Wahrscheinlichkeiten" und wird mit ein wenig Nachdenken genauso schnell
ganz einfach...
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:
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
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.
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.
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
Fail by Design. Dieser Ansatz ist kurde, weil ja pro Standort sicher niemals auch nur annähernd hundert Millionen Karten kursieren.
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
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!?
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 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:
ob das tatsächlich so ist
ob und warum das nötig ist
Denn da taucht immer wieder irgendwas "Bestehendes" auf:
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.
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.
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.
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.
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.
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.
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.
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.
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.
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)
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.
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.
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.
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.
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 ;-).
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!
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?
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.
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.