Fragen zu Big-Endian



  • Hallo Leute,

    wie weit muss man als Programmierer Big-Endian und Little-Endian beachten?

    Hier mal ein Beispiel was ich vorhabe:

    std::vector<unsigned char> meineDaten;
    
    // ...magische Befüllung von 'meineDaten' mit Zufallsdaten (z.B: 100 Byte)...
    
    // hier brauche ich nur die ersten 128 Bit (16 Byte) von meineDaten beginnend vom MSB (most significant bit)
    meineDaten.resize(16); // so korrekt?
    

    Ich generiere eine z.B. Zufallszahl oder ein Hashwert und will die ersten 128 Bit beginnend vom MSB haben. Bei einem std::vector würde ich da einfach '.resize(16)' anwenden. Ist das Vorgehen ok oder ist es problematisch?

    Wenn ich bei C++ Werte habe (int, double oder ein char-array), kommt da immer Big-Endian zum Einsatz oder ist es vom Betriebssystem/Hardware abhängig?

    viele Grüße,
    SBond


  • Mod

    SBond schrieb:

    wie weit muss man als Programmierer Big-Endian und Little-Endian beachten?

    Normalerweise spielt dies nur eine Rolle, wenn man Binärdaten zwischen unterschiedlichen Computern austauschen möchte.

    Hier mal ein Beispiel was ich vorhabe:

    std::vector<unsigned char> meineDaten;
    
    // ...magische Befüllung von 'meineDaten' mit Zufallsdaten (z.B: 100 Byte)...
    
    // hier brauche ich nur die ersten 128 Bit (16 Byte) von meineDaten beginnend vom MSB (most significant bit)
    meineDaten.resize(16); // so korrekt?
    

    Ich generiere eine z.B. Zufallszahl oder ein Hashwert und will die ersten 128 Bit beginnend vom MSB haben. Bei einem std::vector würde ich da einfach '.resize(16)' anwenden. Ist das Vorgehen ok oder ist es problematisch?

    Das ist prinzipiell korrekt. Wirkt sehr umständlich. Die eigentlich interessante Arbeit scheint in dem "magischen" Teil stattzufinden, den du uns nicht zeigst. Die Bitschiebeoperatoren >> und << kennst du?

    Wenn ich bei C++ Werte habe (int, double oder ein char-array), kommt da immer Big-Endian zum Einsatz oder ist es vom Betriebssystem/Hardware abhängig?

    Letzteres.



  • vielen Dank für die Hilfe.

    SeppJ schrieb:

    Das ist prinzipiell korrekt. Wirkt sehr umständlich. Die eigentlich interessante Arbeit scheint in dem "magischen" Teil stattzufinden, den du uns nicht zeigst. Die Bitschiebeoperatoren >> und << kennst du?

    Ja gezeigte Code war nur ein Beispiel. In meinem Falle erzeuge ich einen Hash-Wert, von dem ich dann nur die ersten 16 Bytes für andere Operationen verwende. Ich wollte es hier nicht zu weit aufblähen, daher die "magische Befüllung". Das Arbeiten mit Shift-Operatoren mag ich irgendwie nicht besonders. Habe vor 3-4 Jahren noch Mikroprozessoren in C programmiert und da musste ich diese zu hauf verwenden.

    nochmals Danke 😃


  • Mod

    SBond schrieb:

    vielen Dank für die Hilfe.

    SeppJ schrieb:

    Das ist prinzipiell korrekt. Wirkt sehr umständlich. Die eigentlich interessante Arbeit scheint in dem "magischen" Teil stattzufinden, den du uns nicht zeigst. Die Bitschiebeoperatoren >> und << kennst du?

    Ja gezeigte Code war nur ein Beispiel. In meinem Falle erzeuge ich einen Hash-Wert, von dem ich dann nur die ersten 16 Bytes für andere Operationen verwende. Ich wollte es hier nicht zu weit aufblähen, daher die "magische Befüllung". Das Arbeiten mit Shift-Operatoren mag ich irgendwie nicht besonders. Habe vor 3-4 Jahren noch Mikroprozessoren in C programmiert und da musste ich diese zu hauf verwenden.

    nochmals Danke 😃

    Gerade das klingt doch nach einem Fall für Bitverschiebungen, anstatt Vectorgefrickel. Damit entfallen dann auch Überlegungen zu Endianess, die bei Fragen zu MSB und LSB nichts zu suchen haben.



  • Ok, ich dachte .resize() ist die einfachste Variante.

    Es ist wohl auch meine Schuld, da ich oft zu wenig Informationen gebe wie mir scheint. Ich versuche die Fragestellung meist auch so geziehlt und knapp wie möglich zu beschreiben. Für meinen Hash-Wert nutze ich eine externe Funktion, die mir über die Parameterliste einen 'unsigned char*' (den Hash) und die Hashgröße zurückliefert. Mittlerweile verpacke ich derartige arrays immer in einen std::vector, da die Handhabung für mich einfacher ist.

    Nimms mir bitte nicht übel, falls meine Beschreibungen zu knapp ausfallen (ich meine es ja nicht böse 🙄 )
    Jedenfalls vielen Dank, dass ich von dir und den anderen immer Ratschläge bekomme. Ich weiß es zu schätzen.



  • Normal, sprich meistens, bleibt doch aber die BitOrder erhalten ?

    D.h. der Treiber / die Transportschicht "drehen" Dir deine Bits schon richtig, wenn du binärströme bekommst.

    Sprich wenn du ein unsigned char mit wert 0x05 über netzwerk von einem intel rechner zu einem Motorola Rechner schickst, wird das ankommende char auf dem Motorola auch 0x05 sein und nicht 0xFA
    Das heisst du musst nur die ByteOrder Beachten, bei allen dingen die mehr als 1 byte aufs mal interpretieren muessen.
    Dazu sollte man aber auch Systemfunktionen nutzen ... Netwerk order, Host Ordner und so ... naja je nach Anwendungsfall.

    Genau so ists oft mit anderen Quellen. Wenn es auf dem "Protokoll" eine Bitorder gibt, dann dreht der Treiber, der byteweise liest, die meist schon so, das Bit 0 da landet wo es hingehört (zielplattform bitorder und bitorder aufm Host).

    BitShift gefrickel brauchst doch nur, wenn Protokolle zu interpretieren hasst, wo datentypen hasst die nicht 8bit orientiert sind ....

    CAN Bus beim Fzg z.b.
    oder man selber IO Pins irgendwo ausliest ^^

    Ciao ...


  • Mod

    Es geht bei Endianess nicht um Bits. Bits gibt es aus Sicht des Programmierers überhaupt nicht, die kleinste adressierbare Einheit sind (per Definition) Bytes. Und wenn man aus diesen Bytes größere Datentypen zusammen setzt, dann ist die Reihenfolge sehr relevant.

    Die Bitoperationen arbeiten hingegen mathematisch auf den durch die Bytefolgen repräsentierten Werten. Das heißt, man bekommt auf jeden Fall das richtige Ergebnis, egal wie innendrin die Dinge angeordnet sind.


Log in to reply