Hilfe - Umrechung 5 Byte! Array Dezimal => Hex.

OP (Firma: myself) #7718308
Lesenswert?

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

#7718315
Lesenswert?

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

OP (Firma: myself) #7718355
Lesenswert?

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.

OP (Firma: myself) #7718356
Lesenswert?

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

#7718368
Lesenswert?

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.

OP (Firma: myself) #7718377
Lesenswert?

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

#7718386
Lesenswert?

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)

#7718396
Lesenswert?

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?

OP (Firma: myself) #7718407
Lesenswert?

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

#7718411
Lesenswert?

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.

#7718414
Lesenswert?

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."

#7718419
Lesenswert?

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.

#7718426
Lesenswert?

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)

OP (Firma: myself) #7718439
Lesenswert?

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

#7718441
Lesenswert?

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

OP (Firma: myself) #7718442
Lesenswert?

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 von einem Moderator gelöscht.
#7718452
Lesenswert?

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

OP (Firma: myself) #7718456
Lesenswert?

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

OP (Firma: myself) #7718464
Lesenswert?

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.

#7718466
Lesenswert?

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.

Moderator (Firma: Titel) Persönliche Seite #7718471
Lesenswert?

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.

#7718479
Lesenswert?

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.

Moderator (Firma: Titel) Persönliche Seite #7718481
Lesenswert?

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.

#7718484
Lesenswert?

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.

#7718485
Lesenswert?

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

Gast #7718488
Lesenswert?

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

OP (Firma: myself) #7718490
Lesenswert?

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

#7718509
Lesenswert?

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.

Gast #7718522
Lesenswert?

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

#7718524
Lesenswert?

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

Gast #7718529
Lesenswert?

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

Gast #7718552
Lesenswert?

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

#7718558
Lesenswert?

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

#7718565
Lesenswert?

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.

#7718572
Lesenswert?

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.

#7718580
Lesenswert?

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.

OP (Firma: myself) #7718584
Lesenswert?

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

#7718587
Lesenswert?

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

Moderator #7718614
Lesenswert?

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.

#7718630
Lesenswert?

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

#7718643
Lesenswert?

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.

#7718648
Lesenswert?

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

Moderator (Firma: Titel) Persönliche Seite #7718680
Lesenswert?

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?

OP (Firma: myself) #7718716
Lesenswert?

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

Moderator (Firma: Titel) Persönliche Seite #7718730
Lesenswert?

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?

OP (Firma: myself) #7718781
Lesenswert?

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

#7718846
Lesenswert?

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.

Moderator (Firma: Titel) Persönliche Seite #7718856
Lesenswert?

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)

#7718926
Lesenswert?

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...

Moderator (Firma: Titel) Persönliche Seite #7718965
Lesenswert?

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.

Moderator (Firma: Titel) Persönliche Seite #7718980
Lesenswert?

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...

#7718987
Lesenswert?

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...

(Firma: 1984now) #7718992
Lesenswert?

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.

#7718994
Lesenswert?

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.

OP (Firma: myself) #7719004
Lesenswert?

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

#7719005
Lesenswert?

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

Moderator #7719016
Lesenswert?

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.

Moderator (Firma: Titel) Persönliche Seite #7719026
Lesenswert?

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.

#7719028
Lesenswert?

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

OP (Firma: myself) #7719039
Lesenswert?

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

Moderator (Firma: Titel) Persönliche Seite #7719040
Lesenswert?

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?

OP (Firma: myself) #7719044
Lesenswert?

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

OP (Firma: myself) #7719049
Lesenswert?

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

#7719056
Lesenswert?

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 ...

Moderator (Firma: Titel) Persönliche Seite #7719068
Lesenswert?

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.

OP (Firma: myself) #7719081
Lesenswert?

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

Moderator (Firma: Titel) Persönliche Seite #7719088
Lesenswert?

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.

OP (Firma: myself) #7719091
Lesenswert?

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

#7719097
Lesenswert?

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.

Moderator (Firma: Titel) Persönliche Seite #7719099
Lesenswert?

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.

OP (Firma: myself) #7719104
Lesenswert?

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

#7719122
Lesenswert?

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.

#7719129
Lesenswert?

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.

#7719139
Lesenswert?

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 ;-).

OP (Firma: myself) #7719150
Lesenswert?

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

#7719170
Lesenswert?

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

Gast #7719180
Lesenswert?

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

Moderator (Firma: Titel) Persönliche Seite #7719181
Lesenswert?

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.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.