Was macht diese Funktion?


  • Banned

    https://github.com/apache/commons-codec/blob/master/src/main/java/org/apache/commons/codec/binary/Hex.java#L208

    Ich verstehe die zwei Zeilen innerhalb der Schleife der Methode nicht, aber anscheinend ist diese Funktion im Kontext nicht unwichtig.

    Könnte sie jemand für mich "einfach" erklären? Danke

    Edit: Wie sähe das C-Copendant dazu aus?


  • Mod

    @omggg sagte in Was macht diese Funktion?:

    Edit: Wie sähe das C-Copendant dazu aus?

    #include <stdio.h>
    #include <stdint.h>
    
    const char* encodeHex(unsigned char data[], size_t dataLen, const char toDigits[], char out[]) {
    	// two characters form the hex value.
        for (size_t i = 0, j = 0; i < dataLen; i++) {
            out[j++] = toDigits[(0xF0 & data[i]) >> 4];
            out[j++] = toDigits[0x0F & data[i]];
        }
    	return out;
    }
    
    int main(void) {
    	unsigned char in[] = "ABC";
    	char out[7] = {0};
    	puts(encodeHex(in, 3,  "0123456789ABCDEF", out));
    }
    

  • Banned

    Und jetzt noch eine Erklärung.



  • @omggg sagte in Was macht diese Funktion?:

    Und jetzt noch eine Erklärung.

    Was verstehst du denn nicht?


  • Mod

    Wandelt ein Array von Bytes in ein Array von Zeichen um, die die hexadezimalen Werte der Bytes in Reihenfolge darstellen.

    • data: Ein Array von unsigned chars, das in hexadezimalen Zeichen dargestellt werden soll.
    • dataLen: Die Anzahl der Werte aus data, die dargestellt werden soll
    • toDigits: Das Ausgabealphabet (muss mindestens 16 Zeichen umfassen)
    • out: Ein Array von char, das die hexadezimale Darstellung aufnimmt. Muss mindestens 2 * dataLen lang sein
    • Rückgabewert: Das Array out

  • Banned

    @wob sagte in Was macht diese Funktion?:

    @omggg sagte in Was macht diese Funktion?:

    Und jetzt noch eine Erklärung.

    Was verstehst du denn nicht?

    Alles. 😢

    Ich dachte, das Ding wandelt eine Dezimalzahl (bzw. Binärzahl) in eine Hexadezimalzahl um und gibt dann einen String zurück. Nein?

    Also... base10 to base16 ...



  • @omggg

    es geht darum, die Hex-Werte für die nibbles rauszuziehen. Also: Ein Byte hat 8 Bit, das sind 2 Nibbles mit jeweils 4 Bit. Nehmen wir das Byte 0xAB, schieben 4 Bit nach rechts raus (bit-shift) und legen die Maske 0xF darüber:

    0xAB >> 4 & 0xF so erhalten wir 0xA (nibble links) und um das rechte nibble zu kriegen wenden wir einfach nur die Maske 0xF an, also 0xAB & 0xF so erhalten wir 0xB für das rechte nibble.

    Tags: Bitoperatoren und Bitmaske.

    MFG 😉



  • @omggg sagte in Was macht diese Funktion?:

    Alles.

    Wenn du einzelne Dinge in einzelnen Zeilen nicht verstehst, helfe ich gerne, wenn du genau sagst, was "alles" ist. Ist es das [j++]? Ist es das &? Ist es das >> 4?

    Ich dachte, das Ding wandelt eine Dezimalzahl (bzw. Binärzahl) in eine Hexadezimalzahl um und gibt dann einen String zurück. Nein?

    Die Eingabe ist doch ein final byte[] data (in Java) bzw. das unsigned char data[] in C. Als eine beliebig lange Kette von irgendwelchen Bytes. Das können Binärdaten sein, Strings, Zahlen, ... - dieser Funktion ist das egal, sie guckt nur auf die Bytes.

    Und diese werden dann einzeln nach Hex umgewandelt und dann in den übergebenen Speicherbereich reingeschrieben.


  • Banned

    Keine Fragen mehr.

    Edit: Doch eine noch. Steht im Ergebnis nun die Hexadezimal-Repräsentation der Zahl als String oder nicht

    ?



  • @omggg

    das Ergebnis von Bit-Shift ist immer ein Integer.

    MFG

    Edit: Das war in JavaScript immer der Geheimtipp um an den Integer-Teil einer float zu kommen: 3.9 >> 0 ergibt genau 3.


  • Banned

    @_ro_ro

    Ich glaube, du irrst dich.

    Aber der JS-Trick ist gut. 😉



  • @omggg

    glauben heißt nicht wissen 😉


  • Banned

    Informatiker machen nur selten absolute Aussagen. 😉

    Aber vielleicht sollte ich das einfach mal ausprobieren:

    public class MyClass {
        private static char[] encodeHex(final byte[] data, final int dataOffset, final int dataLen, final char[] toDigits, final char[] out, final int outOffset) {
            // two characters form the hex value.
            for (int i = dataOffset, j = outOffset; i < dataOffset + dataLen; i++) {
                out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
                out[j++] = toDigits[0x0F & data[i]];
            }
            return out;
        }
        public static void main(String args[]) {
          byte[] data = {123};
          int dataOffset = 0;
          int dataLen = data.length;
          char[] toDigits = "0123456789abcdef".toCharArray();
          char[] out = new char[dataLen * 2];
          int outOffset = 0;
          encodeHex(data, dataOffset, dataLen, toDigits, out, outOffset);
    
          System.out.println(new String(out)); // -> 7b
        }
    }
    

    https://www.jdoodle.com/ia/11T6

    @_ro_ro Du hast Dich geirrt, es wandelt in die Hex-Schreibweise um.



  • @omggg sagte in Was macht diese Funktion?:

    Du hast Dich geirrt, es wandelt in die Hex-Schreibweise um.

    Ein Integer ist es dennoch 😉


  • Banned

    @_ro_ro sagte in Was macht diese Funktion?:

    @omggg sagte in Was macht diese Funktion?:

    Du hast Dich geirrt, es wandelt in die Hex-Schreibweise um.

    Ein Integer ist es dennoch 😉

    Eigentlich, ein Zeichen-Array 😉

    Aber ja, im Prinzip ist alles, was um uns herum ist und wir sehen, nur eine Zahl. 😅



  • @omggg

    achja und noch etwas: auch eine integer-Maske liefert den integer-Anteil einer Zahl.

    3.9 & 0xFF ergibt 3.

    Und wie man hex-Strings in Zahlen und umgekehrt umwandelt weiß Du ja jetzt 😉

    mfg


  • Banned

    JavaScript != Java 😉

    Aber in diesem Fall ein schöner Hack...

    Schönen Abend allerseits gewünscht! 🙂



  • @omggg

    der Hack geht auch in Perl und in PHP. Wer schreibt hier eigentlich von wem ab!?

    Schönen Sonntag 😉


  • Banned

    @_ro_ro sagte in Was macht diese Funktion?:

    Wer schreibt hier eigentlich von wem ab!?

    Immer der, der fragt 😁

    Schönen Sonntag!


  • Banned

    In the Hex.encodeHex method, the two lines within the loop:

    out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
    out[j++] = toDigits[0x0F & data[i]];
    
    

    do the following:

    • Convert the upper 4 bits of data[i] to a hexadecimal character and store it in out.

    • ListenpunktConvert the lower 4 bits of data[i] to a hexadecimal character and store it in out.
      A C equivalent would be:

    char hexDigits[] = "0123456789abcdef";
    
    void encodeHex(const unsigned char* data, int dataLen, char* out) {
        for (int i = 0, j = 0; i < dataLen; ++i) {
            out[j++] = hexDigits[(data[i] & 0xF0) >> 4];
            out[j++] = hexDigits[data[i] & 0x0F];
        }
    }
    
    

    This function performs the same conversion from bytes to hexadecimal characters.


Log in to reply