Dieter: Wie mit 64Bit Blöcken arbeiten

Hallo,
also ein normaler Computer, benutzt i.d.R. ein 32 Bit Prozessor.

Jetzt gibt es aber Verschlüsselungsalgorithmen, die z.B. eine Blöcklänge von 128 Bit, bzw. 64 Bit linker & 64 Bit rechten Block besitzen.
Dazu gehört z.B. AES, aber auch DES benutzt Zeitweise 48 Bit Blöcke.

Auf einem normalen Computer kann man in einer Integer Variable leider nur max. 32 Bit speichern, so dass man einen gesamten Block (linke/rechte Hälfte) nicht in einer Variablen speichern kann.

Wie wird dieses Problem in Programmen gelöst?

Wird jetzt ein 64 Bit großer linker Block in zwei 32 Bit Blöcke unterteil?
Oder wird jedes Byte in ein Array gespeichert, und dann jedes Arrayelement entsprechend "behandelt"?

Grüße
Dieter

  1. Sup!

    Entweder, die Programmiersprache kapselt für Dich die Hardware und stellt 64-Bit-Operationen auch auf einem 32-Bit-Prozessor zur Verfügung, oder Du musst Dich selbst drum kümmern, und einen 64-Bit-Block aus 2x32 oder 4x16 oder 8x8 Bit zusammensetzen, und ggf. die Operationen aufteilen, so dass sie auf Teilblöcken ausgeführt werden. Bei einer Addition z.B. addierst Du erst die niedrigwertigen Sub-Blöcke, dann die höherwertigen, bei einer logischen Operation ist die Ausführungsreihenfolge egal, etc..

    Gruesse,

    Bio

    --
    Never give up, never surrender!!!
    1. Hallo,
      aber wie sieht es denn z.B. mit Bit-Verschiebungen aus?
      Dort wäre es doch schon relevant ob man 2x32 Bit Blöcke verschiebt oder 1x64Bit block, oder?

      Grüße
      Dieter

      1. 你好 Dieter,

        aber wie sieht es denn z.B. mit Bit-Verschiebungen aus?
        Dort wäre es doch schon relevant ob man 2x32 Bit Blöcke verschiebt oder
        1x64Bit block, oder?

        Wenn die Plattform das nicht nativ einbaut (viele Prozessoren können mit
        Größen, die der natürlichen Größe nicht entsprechen, umgehen) muss man das
        halt per Software emulieren. Ist dann zwar sehr langsam, aber nicht zu
        ändern.

        再见,
        克里斯蒂安

        --
        Das Leben ist wie ein Kartenspiel: was dir gegeben wurde, ist vorbestimmt. Doch wie du damit spielst, ist deine Entscheidung.
        http://wwwtech.de/
  2. Hi Dieter,

    Auf einem normalen Computer kann man in einer Integer Variable leider nur max. 32 Bit speichern,

    Je nach Prozessor.

    In C gibt es neben den Typen int bzw. unsigned int auch long int bzw. unsigned long int mit doppelter Länge.

    Gruß,
    Gunnar

    --
    „Weisheit ist nicht das Ergebnis der Schulbildung, sondern des lebenslangen Versuchs, sie zu erwerben.“ (Albert Einstein)
    1. Hallo,

      In C gibt es neben den Typen int bzw. unsigned int auch long int bzw. unsigned long int mit doppelter Länge.

      Dabei ist die "doppelte Länger" allerdings 32 Bit, denn früher wurde 16 Bit für int benutzt.

      Grüße
      Dieter

      1. Hallo,

        In C gibt es neben den Typen int bzw. unsigned int auch long int bzw. unsigned long int mit doppelter Länge.

        also wenn ich z.B:
        unsigned long long test = 10 000 000 000; (ohne Leerzeichen)

        schreibe, dann erhalte ich sowohl von DevCpp als auch von GCC den Fehler:
        Integer constant is to larg for "long" type.

        Auch wenn ich per scanf(); eine große Zahl, allerdings kleiner als 2^62 einlese, wird diese per prinft("%u",zahl); immer mit 4.294.967.295 ausgegeben.

        Laut Wikibooks kann man dort allerdings 64 Bit zahlen speichern, weiß jmd. woran das liegen kann?

        Benutze WinXP.

        Grüße
        Dieter

        1. Hallo Dieter

          Auch wenn ich per scanf(); eine große Zahl, allerdings kleiner als 2^62 einlese, wird diese per prinft("%u",zahl); immer mit 4.294.967.295 ausgegeben.

          wie wäre es, wenn Du Dir die Werte von

          ULLONG_MAX
              ULONG_LONG_MAX

          ausgeben lassen würdest, die typischerweise in limits.h definiert werden.

          Freundliche Grüße

          Vinzenz

          1. Hallo,
            obwohl für die Konstanten 2^62 definiert wurde, erhalte ich bei der Ausgabe dennoch nur die 4,2 Mrd (2^32).

            Grüße
            Dieter

            1. obwohl für die Konstanten 2^62 definiert wurde, erhalte ich bei der Ausgabe dennoch nur die 4,2 Mrd (2^32).

              signed vs. unsigned

              1. Hallo,
                dies ist auf unsigned.

                Allerdings:

                long long:
                signed ist der Bereich bei ca.: -2^61 bis +2^61
                unsigned: 0 bis 2^62

                int:
                signed ca.: -2^31 bis +2^31
                unsigned: 0 bis 2^32

                Je nach Compiler kann bei signed der Betrag des positive Bereich um 1 kleiner sein, weil die 0 auf 2 Arten dargestellt werden kann.

                Grüße
                Dieter

                1. 你好 Dieter,

                  Je nach Compiler kann bei signed der Betrag des positive Bereich um 1
                  kleiner sein, weil die 0 auf 2 Arten dargestellt werden kann.

                  Nein. Wie die 0 dargestellt wird ist auf x86-Plattformen definiert, das
                  machen alle Compiler gleich. Es kann aber je nach Plattform variieren.

                  再见,
                  克里斯蒂安

                  --
                  73.255437% der Statistiken spielen eine Genauigkeit vor, die durch die angewandte Methode nicht gerechtfertigt wird.
                  http://wwwtech.de/
      2. 你好 Dieter,

        In C gibt es neben den Typen int bzw. unsigned int auch long int bzw.
        unsigned long int mit doppelter Länge.

        Dabei ist die "doppelte Länger" allerdings 32 Bit, denn früher wurde 16
        Bit für int benutzt.

        Wie gross genau die Datentypen sind, hängt stark von der Plattform und
        manchmal auch vom Compiler ab. Häufig ist int die natürliche Größe auf einer
        Plattform, genau wie long (also sizeof(int) == sizeof(long)), muss aber
        nicht so sein. Viele Compiler unterstützen dann noch long long, was dann
        das doppelte der natürlichen Größe darstellt.

        Um die Plattform-Probleme zu umgehen, definiert der POSIX-Standard
        sys/types.h, wo genauer festgelegte Datentypen definiert sind: int8_t,
        u_int8_t, int16_t, u_int16_t, int32_t, u_int32_t, int64_t, u_int64_t.
        Vermutlich fehlen da noch einige Typen, aber das sind wohl die wichtigsten
        Integer-Typen.

        再见,
        克里斯蒂安

        --
        Die Summe zweier gerade Primzahlen ist immer eine Quadratzahl.
        http://wwwtech.de/
  3. Moin!

    Auf einem normalen Computer kann man in einer Integer Variable leider nur max. 32 Bit speichern, so dass man einen gesamten Block (linke/rechte Hälfte) nicht in einer Variablen speichern kann.

    Wie wird dieses Problem in Programmen gelöst?

    Jeder vernünftige Prozessor hat zusätzlich zu seinen Registern noch diverse Flags, welche man für die unterschiedlichsten Dinge nutzen kann.

    Für arithmetische Belange gibt es beispielsweise das Carry-Flag, welches z.B. bei Additionen das Übertragsbit enthält, das Zero-Flag (wird gesetzt, wenn eine Operation Null ergibt), das Overflow-Flag (für vorzeichenbehaftete Rechenoperationen) sowie das Negativ-Flag (gesetzt, wenn der Integerwert negativ ist). Ich muß allerdings zugeben, dass diese Ausführungen sich konkret nur auf die Prozessorreihe 6502/6510 beziehen (bei dem weiß ich es), ich kann mir aber kaum vorstellen, dass x86er das grundlegend anders lösen können.

    Eine Addition beliebig großer Werte wird mit dem Carry-Flag dann schrittweise vom LSB zum MSB durchgeführt. Vor Beginn der Addition wird das Carry gelöscht, die Addition des LSB setzt oder löscht das Carry, sofern ein Übertrag errechnet wurde, und mit diesem Ergebnis wird das nächst höhere Byte/Word/Longword addiert.

    Wer sich damit assemblermäßig nicht rumquälen will, und seine Programmiersprache auch keine direkte Unterstützung liefert, muß sich vermutlich nach einer passenden Mathe-Bibliothek umsehen. :)

    • Sven Rautenberg