Forum: PC-Programmierung Rechnen mit unsigned char*


von DarkBlue (Gast)


Lesenswert?

Hi,

ich habe mal eine Frage.
Ich versuche gerade eine Kryptokarte zu programmieren, diese kann
bestimmte Rechenoperationen durchführen, alles Modulare Arithmetik. Das
heißt sie kann A*B mod N, A^B mod N und A mod N rechnen. Da es sich um
bigints handelt, also alles weit über long oder sonstiges, rechnet die
Karte mit unsigned char* . OK soweit so gut, ich kann mir also einen
Array bauen und berechnungen durchführen, allerdings wenn ich dann
berechnungen durchführen möchte wie addieren oder subtrahieren hab ich
ein Problem. Kann mir da vielleicht jemand weiterhelfen.

Also die Frage nochmal in kurzform, wie addiere oder subtrahiere ich
zwei unsigned char arrays?

Hoffe ihr könnt mir weiterhelfen.
Falls noch fragen sind einfach fragen ;)

Vielen Dank schon mal
Gruß
DarkBlue

von Karl heinz B. (kbucheg)


Lesenswert?

Ich denke mal deine Karte rechnet nicht mit unsigned char*.

Was du wahrscheinlich hast sind Funktionen wie

  void Add( unsigend char* Arg1,
            unsigned char* Arg2,
            unsigned char* Result );

Stimmts?

Die Funktion moechte dann von dir haben, dass du
entsprechend grosse Arrays anlegst und die jeweils
per Pointer in die Funktion stopfst:


  unsigned char Zahl1[20];
  unsigned char Zahl2[20];
  unsigned char Result[20];

  Add( Zahl1, Zahl2, Result );

Wie du jetzt aber diese Arrays befüllen musst, kann
ich dir auch nicht sagen. Da gibt es viele Möglichkeiten
zb
* als ganz normale Strings
    strcpy( Zahl1, "1234" );

* als Zeichenketten die rechts aligned sind.
    Zahl1[0] = ' ';
    Zahl1[1] = ' ';
    ...
    Zahl1[16] = '1';
    Zahl2[17] = '2';
    Zahl3[18] = '3';
    Zahl4[19] = '4';

* als fortlaufende Binärzahl, beginnend beim letzten Byte
  des Arrays.
  (so wie long aus 4 Byte besteht, besteht halt diese Zahl
   aus 20 Bytes)

* die Frage ist dann, wass ist mit Byte-Alignment?
  sind die immer rechts aligned, oder links aligned?
  Können die Zahlen unterschiedliche Anzahl Bytes haben?

von ich (Gast)


Lesenswert?

Bitte nicht angepisst fühlen jetzt.
Mache dir bitte nocheinmal ganz genau klar, wie in der Grundschule die
schriftliche Addition gemacht wurde:
1. Einer addieren und Übertrag merken
2. Zehner addieren und dazu Übertrag addieren, neuen dabei entstandenen
 Zehnerünertrag merken
3. ...

Mit deinen Arrays läuft es im Prizip genau so: vom LSB her aufdröseln
und Übertrag merken.

Gruß

von DarkBlue (Gast)


Lesenswert?

Danke erstmal :)
und ich fühl mich auf keinen Fall angepisst ;) ich hab gefragt und ihr
habt geantwortet, freu ich mich doch drüber.

Also zum ersten Post, ja das ist richtig, rechnen tut die Karte ja
sowieso binär. Aber ich gebe in die Funktionen eben unsigend char*
rein. Das ist ja soweit auch alles kein Problem, ich kann diese
Funktionen auch ansprechen und bekomme mein Ergebnis dann in einerm
unsigned char* wieder, alles im BigEndian Format.

Das Problem ist jetzt eben nur das ich keine Funktion zum addieren
habe. das heißt ich muss mir selber eine schreiben.
Womit ich jetzt zur zweiten Antwort komme.
Ja das mit dem wie in der Schule mit dem übertrag ist ja OK, aber ich
habe ja diese unsigned char, wenn ich jetzt zwei Array habe sagen wir
mal:
  {0x00,0x00,0xF1,0xFF}
+ {0x00,0x12,0x0C,0x1A}
= {0x00,0x12,0xFE,0x19}

grad nich so ganz sicher ob das stimmt ^^
aber wenn ich jetzt in C die einzelnen Bytes addiere hab ich doch dann
FF + 1A = 119 bei den letzten Bytes. Das Ergebnis ist aber dann größer
als 1 Byte, wegen des übetrags.
Wenn ich per Hand rechne, nehm ich mir ja auch nicht 1 Byte sondern nur
4 Bit, also nur F + A und kann dann so auch leicht rechnen.
Es stellt sich mir jetzt nur die Frage wie ich das ganze
programmiertechnisch angehe, so das es auch noch recht effektiv ist.
Wenn mir da jemand einen Ansatz geben könnte wäre das nett :)

Vieln dank und schönen Gruß
DarkBlue

von Karl heinz B. (kbucheg)


Lesenswert?

du addierst 2 Byte.
Das machst du aber nicht mit Byte Arithmetik, sonder mit int
Arithmetik. Ist das Ergebnis größer als 255, dann hast
du einen Übertrag, der in der nächsten Stelle berücksichtigt
werden muss. Das Ergebnis für diese Stelle ist natürlich %256
zu nehmen

Das ist nichts anderes, als wenn du zu fuss rechnest:

   8 + 7  ergibt 15
   15 ist größer als 9 (deine größte mögliche Ziffer)
   also gibt es einen Übertrag in die nächste Stelle
   und das Ergebnis ist %10 zu nehmen
   Das Ergebnis ist daher 5, und bei der Addition der nächst
   höherern Stelle ist ein Übertrag von 1 zu berücksichtigen.

Du rechnest halt nicht im 10-er System, sondern im 256-er
System. Aber sonst ist alles gleich


  0xFF + 0x1A  ergibt 0x119

  0x119 ist größer als 0xFF -> daher
     das Ergebnis für diese Stelle bereinigen
           0x119 & 0xFF ->  0x19
    und für die nächst höhere Stelle einen Übertrag von 1
    (der kann nie größer sein) vorsehen.

ganz genau so, wie du es in der Schule gelernt hast.
Der Trick besteht darin, dass du die Addition selbst
mit einem 'größeren' Datentyp machen musst.
Ganz genau so, wie auch beim kleinen 1*1. Wenn du
dich nur auf den Zahlenraum 0 bis 9 beschränkst, kannst
du keine 2-stelligen Additionen machen, da die Addition
8 + 7 ergibt fünfzehn  nicht machbar ist, da es das Symbol
'fünfzehn' im Zahlenraum 0 bis 9 nicht gibt.

von ich (Gast)


Lesenswert?

in wie weit das jetzt effektiv ist, musst du testen
ein erster Ansatz wäre
0. temp. Hilfsvariable(16Bit groß) anlegen
1. beide Zeiger auf das LSB umbiegen
2. LSBs addieren Ergebnis in temp
3. low-Byte von temp in LSB des Ergebnisarrays
4. High-Byte von temp ins low-Byte shiften (das ist der gemerkte
Übertrag)
5. nächsthöhere Bytes der Argumente addieren + temp
weiter mit 3. solange bis du meim MSB angekommen bist

Ob du nun 4Bits oder 8Bits aufeinmal addierst ist nur eine Frage der
Vorstellung und der Kopfrechenfähigkeiten. Prinzipiell ist das völlig
identisch bis auf die Anzahl der Schleifendurchläufe.

Gruß

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.