Interpretationsproblem in C

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Interpretationsproblem in C


      Spoiler anzeigen
      Example decompression code (in 'C'):

      char* EncodedString;
      char* DecodedString;
      char mask;int pos=0;
      int dpos=0;
      while (EncodedString[pos] != 0){
      if (pos%8 == 0)
      mask=EncodedString[pos];
      else {
      if ((mask & (0x1 << (pos%8))) == 0)
      DecodedString[dpos++] = EncodedString[pos] - 1;
      else
      DecodedString[dpos++] = EncodedString[pos];
      }
      pos++;
      }



      Gibts hier irgendwen der mir diese Passage erklären kann, ich bin nicht so fit in bitweisen Operationen. Ich möchte diese Passage in eine andere Sprache übertragen welche völlig andere Syntax hat und die bitweisen Operationen in dieser Form nicht zulässt. Wäre nett wenn mir irgendwer die Methodik umschreiben könnte :D

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Aiolos ()

    • Formatier das ganze mal etwas schöner und sag in welche Sprache du das umschreiben willst.

      Wir haben 100 Hacker und Hacksen gefragt: "Was die schrecklichste Programmiersprache, in der du je programmiert hast?"
      1. Java
      2. PHP
      3. Visual Basic
      4. BASIC
    • so habs mal etwas besser dargestellt ich dacht die codebox hier wäre praktisch genug dafür.
      ich möchte das in einen basicartigen dialekt übersetzen, aber es geht mir rein um die methode es geht mir um kein fertiges ergebnis ich möchte nur verstehen was da passiert weil ich in c und diesen bitweisen shift nicht bewandert bin :D

      okay edit:
      noch ne kurz umschreibung
      aus einer datei wird ein binär string ausgelesen der "null-terminated" ist, d.h. er endet mit 0x00. Dieser String wird dann in den Char Array encodedString eingetragen und dann beginnt die eigentliche Prozedur:
      Der String selber besteht aus 3 Teilstring welche ebenfalls null-terminated sind, aber hier codiert und zwar +1 d.h. sie hören mit 0x01 auf, die ganzen anderen zeichen sind ebenfalls codiert welche irgendwie mit dem startbyte zusammen hängt. Das kann ich noch als Ergänzung dazu sagen...

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Aiolos ()

    • Während encodedstring an der Stelle pos ungleich 0 ist

      wenn pos Modulo 8 0 ist, dann wird mask zum Wert von encodedstring an der Stelle pos (Modulo gibt den Rest einer Division aus. Also pos/8 und davon den Rest. Bei 8, 16, 24 usw also 0)

      ansonsten

      wenn mask und (0x1 << pos%8) == 0 d.h. wenn eins von den beiden mit und verknüpften Elementen falsch ist, tritt das == 0 ein, ansonsten (beide wahr) wird der Wert "mask & (0x1 << pos%8)" 1 bzw. wahr .

      das 0x1 << pos%8 verschiebt Bits. 0x1 ist ne 1 in hexadezimaler Schreibweise verschiebt man die 1 also nach links (und füllt hinten wieder mit 0en auf).

      Ich verstehe allerdings den Sinn kein bisschen, weil man mit 0x1 anfängt (also 1) und dann nach links verschiebt, was die Zahl nur größer und nicht kleiner macht. "0x1 << pos%8" ist also immer >0. (Es sei denn man stößt irgendwann beim verschieben an die Grenzen der Datenstruktur, allerdings verschiebt man nur um höchstens 7 bit (pos%8 wird nie größer als 7), daher kommts denkich nicht soweit)

      Läuft das Programm genauso wenn du das (0x1 << pos%8) einfach durch ne 1 ersetzt? :D

      EDIT: Also ich hab grad mal ne kleine Schleife programmiert die alle Werte für (0x1 << pos%8) mit 0<pos<64 ausrechnet und es kommt nur 1,2,4,8,16,32,64,128 als Lösung (alles ist >0 und damit wahr).

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von ^woOt ()

    • Brainfuck-Quellcode

      1. char* EncodedString;
      2. char* DecodedString;
      3. char mask;int pos=0;
      4. int dpos=0;
      5. //Solange nicht 0x00 im String steht
      6. while (EncodedString[pos] != 0) {
      7. //Jede achte Stelle also: 0, 8, 16, 24.....
      8. //Ändere die Maske zu dem an der Stelle stehenden Zeichen
      9. if (pos%8 == 0) {
      10. mask = EncodedString[pos];
      11. } else {
      12. //Hier wird Bitweise die Maske mit einer 2er Potenz je nach Stelle verundet. Also als Beispiel
      13. //An der Stelle 3 wird sowas gerechnet (Maske ist hier als BSP.: das Zeichen a):
      14. // 01100001 (Hex 61 = Ascii für Zeichen a)
      15. // 00000100 (pos = 3, 3%8 = 3 und dann noch schnell (0x1 << 3) 1 * 2^3 = 8 gerechnet)
      16. // --------------
      17. // 00000000 (Ergebnis bei Bitweise und)
      18. if ((mask & (0x1 << (pos%8))) == 0)
      19. DecodedString[dpos++] = EncodedString[pos] - 1;
      20. else
      21. DecodedString[dpos++] = EncodedString[pos];
      22. }
      23. pos++;
      24. }
      Alles anzeigen


      Welche Zeichen in dem else Zweig also anders gehandhabt werden hängt von ihrer Position ab. An den Positionen 0, 8, 16, 24... werden z.B die Zeichen: a,c,e.... anders behandelt
      An den Positionen 3, 11, 19, 27 die Zeichen: D, L ..., d,l ... anders behandelt usw usf....
      Was das allerdings bringen soll kannich dir nicht sagen. Da die Strings aber Encoded/Decoded heißen nehme ich mal an, dass es sich um eine ganz primitive Form des verschlüsselns handelt.

      Hoffe das war klar genug? Wenn du die Sprache sagst kann dir sicher jemand das ganz hier auch schnell als Code rauswerfen dürfte nit sooo schwer sein.

      MFG

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von downtimes ()

    • genau genommen ist diese codierung in replays zu finden, der einzige teil den ich noch nicht umsetzen konnte, steht der mapname und der host drinne :D

      danke für eure antworten - auf ans werk :D
    • Da 0x1 << pos%8 immer wahr ist, kann man das Programm auch umschreiben:

      Quellcode

      1. char* EncodedString;
      2. char* DecodedString;
      3. char mask;int pos=0;
      4. int dpos=0;
      5. while (EncodedString[pos] != 0){
      6. if (pos%8 == 0)
      7. mask=EncodedString[pos];
      8. else {
      9. if (mask == 0) DecodedString[dpos++] = EncodedString[pos] - 1;
      10. else DecodedString[dpos++] = EncodedString[pos];
      11. }
      12. pos++;
      13. }
      Alles anzeigen

      (denn wenn mask 0 ist, wird die ursprüngliche Abfrage 0 & 1 == 0 (0&1 ist falsch, also wird encodedstring[pos] -1 gewählt), wenn mask 1 ist, ist die Abfrage 1&1 == 0 (1&1 ist aber 1, also einfach encodedstring[pos])

      Aber woher kommt das Programm eigentlich und warum war das 0x1 << pos%8 überhaupt drin!?
    • Da 0x1 << pos%8 immer wahr ist, kann man das Programm auch umschreiben:


      Das ist nicht wirklich richtig. Schau dir mal in ner ruhigen Minute den unterschied zwischen & und && an vllt merkste dann wo dein denkfehler ist. Das boolshe und und das Bitweise und sind 2 komplett unterschiedliche paar Schuhe.

      Ich muss mich aber Tass anschließen. ist einfach einfacher wenn man per Pastebin oder so wie ichs gemacht hab Codestellen kopieren kann und leichter Kommentare einfügen kann.

      MFG
    • Hä was? Ich kenn den Unterschied ziemlich gut, aber in dem Fall is es wie folgt:

      Er Vergleicht x1 mit x2.
      x1 = mask
      x2 = 0x1 << pos%8

      Bitweises Und macht folgendes:
      Fall x1 x2 Erg
      1 0 0 0
      2 0 1 0
      3 1 0 0
      4 1 1 1


      Da x2 immer >0 ist und alles ungleich 0 wahr (also 1) ist, gibt es nurnoch die Fälle:
      Fall x1 x2 Erg
      2 0 1 0
      4 1 1 1


      Also entweder ist Mask 0 oder ungleich 0.

      Wenn Mask 0 ist, wird "mask & (0x1 << pos%8)" also 0 (Fall 2), wenn Mask ungleich 0 ist wird es 1 (Fall 4). Sollte Mask also 0 sein, trifft das "if ((mask & (0x1 << (pos%8))) == 0)" zu und "DecodedString[dpos++] = EncodedString[pos] - 1;" wird ausgeführt (Fall 2). Im anderen Fall (4) trifft "if ((mask & (0x1 << (pos%8))) == 0)" nicht zu und "else DecodedString[dpos++] = EncodedString[pos];" wird ausgeführt.


      Und ja, es kann sein, dass ich was nicht raff, aber dann mach mich genau darauf aufmerksam, weil meine Logik erscheint mir logisch :D

      EDIT: Verdammt vergiss alles, habs verrafft :D Jo wird jeder Bit einzeln logisch und verknüpft unso. 0x1 << pos%8 wird dann 1, 2, 4, 8, 16, 32, 64, 128 also:

      00000001
      00000010
      00000100
      00001000
      00010000
      00100000
      01000000
      10000000

      Wenn Mask also 98 ist

      01100010

      wird mask & 0x1 << pos%8 (je nach pos)

      00000000
      00000010 -- 2
      00000000
      00000000
      00000000
      00100000 -- 32
      01000000 -- 64
      00000000

      Mein if mask == 0 kann also auch != 0 sein und trotzdem wird mask & 0x1 << pos%8 == 0.

      (Hab mir das jetzt alles nur nochmal zur verdeutlichung aufgeschrieben, aber schicks einfach mal so ab, vllt hilfts ja noch dem TE und es war nicht nur für mich :D)

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von ^woOt ()

    • ^woOt ist doch kein Problem.
      Wie ich grade eben im Bett festgestellt hab lag ich auch total Falsch mit dem was ich gesagt hab. Und weil man ja sowas nicht einfach stehen lassen kann jetzt nochmal die Textuell wirklich RICHTIGE Beschreibung des Algorithmus:
      (Das alte lass ich mal stehen, damit sich Leute drüber totlachen können ^^)

      Der Encoded String ist in logische Blöcke a 8 Zeichen unterteilt (Block 0-7, Block 8-15 usw usf.). Bei diesen Blöcken ist jeweils das erste Zeichen die Maske die bestimmt wie mit dem eigentlichen Text verfahren werden soll. Bei der Maske sind die Bits = 1 sehr entscheidend. Als Beispiel nehmen wir mal den String "bHbmmp_Wcemu\0" wobei _ ein LeerZeichen darstellen soll und \0 die Nullterminierung.
      Jetzt nimmt unser Algo das Zeichen an der Stelle 0, in unserem Fall das b. Das hat die Dualrepräsentation 01100010 nach Ascii Zeichensatz. Durch dieses b wissen wir nun das die 1. die 6. und die 7. Stelle NORMAL übertragen werden (da diese Stellen eine 1 als Bit vorweisen) und alle anderen Stellen werden eins verringert, d.h die Buchstaben werden im Alphabet eins nach "vorne" geschoben ( aus b -> a).

      Also nehmen wir uns die Zeichen einzeln her. Erst das H, das steht an der ersten Stelle also wird es einfach übertragen. Dann das b das steht an Stelle "2" die wird eins verringert also wird aus b ein a. Dann das m das steht an "3." Stelle wird also auch um eines verringert und zum l. Das gleiche mit dem nächsten m -> l. Dann das p steht an der "5.", wird also auch verändert und wir erhalten ein o. Die "6." und "7." Stelle hingegen werden normal übertragen.

      Bis hierher haben wir also erhalten "Hallo_W" wobei zu beachten ist, dass die Maske nicht mit übertragen wird. Nun kommt der nächste Block bei dem die Maske ein c ist. Duale räpresentation laut ASCII ist in diesem Fall 01100011 das bedeutet Stelle "8." "9." "14." "15." werden normal übertragen. Nehmen wir uns wieder die Buchstaben her dann kommt ein e an Stelle "9". Das wird laut Maske wieder einfach übertragen. Dann ein m an Stelle "10" das wird zu l verringert und Schlussendlich ein u an Stelle 11 das zu t verringert wird und dann hört der Algo wegen der nullterminierung auf.

      Als Ergebnis erhalten wir "Hallo_Welt"
      Wichtig hierbei ist auch das dieser String NICHT Nullterminiert ist du das also eventuell noch manuell hinzufüen solltest!

      So ich hoffe nu diese textuelle Beschreibung und das kleine konstruierte Beispiel von mir haben dir geholfen den Algorithmus zu verstehen.
      Diesesmal dürfte es auch richtig sein :D

      Edith meint: Wenn du dir sicher gehen willst, dass ich richtig liege kannste die Funktion ja einfach mal mit meinem String füttern und dir ausgeben lassen was rauskommt (sofern du halbwegs C Programmieren kannst)

      MFG downtimes

      PS.: dafür das ich Nachts um 2 extra nochmal an PC bin nur um das klarzstellen will ich aber mindestens ein +1! :D
    • Der Programmablauf in Einzelschritten:
      Spoiler anzeigen
      encodedstring = "bHbmmp_Wcemu\0"

      encodedstring[0] != 0 stimmt (da encodedstring[0] = b)

      pos%8 == 0 stimmt, also wird mask = b

      pos++

      von vorne

      1%8 == 0 stimmt nicht, also else

      b & (0x1 << (1%8))

      b = 98 = 01100010
      0x1 = 00000001
      0x1 << 1 = 00000010

      01100010
      &
      00000010
      ------------
      00000010 = 2

      2 == 0 stimmt nicht

      also

      decodedstring[dpos++] = encodedstring[pos] (= decodedstring[1] = encodedstring[1] = H)

      pos++

      2%8 != 0, also if mask & 0x1 << pos%8

      mask = b = 01100010
      0x1 << 2%8 = 0x1 << 2 = 00000100

      01100010
      &
      00000100
      ------------
      00000000 = 0

      0 == 0 stimmt, also

      decodedstring[dpos++] = encodedstring[pos] - 1 (=decodedstring[2] = b - 1 = a)

      uswusw


      Also die If-Abfrage guckt einfach nach, welche Bits der Maske 1 sind und übergibt die Stellen an denen der Bit 1 ist einfach an decodedstring, alles andere wird -1 genommen. Du hast also recht ;)

      Mein Problem am Anfang war, dass ich gedacht habe, ein bitweises Und vergleicht die Dezimalen Werte der Operanden und nicht jeden Bit der dualen Werte.

      Ein Anmerkung hab ich allerdings noch:

      Spoiler anzeigen

      Wenn die Maske dann a wird:

      a = 97 = 01100001

      es wird wieder überprüft:

      if mask & (0x1 << (pos%8))

      mask = 01100001
      pos%8 = 9%8 = 1 = 00000001
      0x1 << 1 = 00000010

      01100001
      &
      00000010
      ------------
      00000000 = 0

      Der 2^0 Bit gehört also nicht zur Maske, da er durch die grundsätzliche Verschiebung um 1 Bit nach links aus der Überprüfung fällt.

      Maske sind also nur die 2^8 bis 2^1 Bits des Wertes. (Ist ja klar, da ein Block nach der 8ten Stelle (welche die Maske angibt) nur die nächsten 7 Stellen belegen kann, da danach die nächste Maske folgt. Die Maske braucht also nur 7 Bits.)
    • Benutzer online 1

      1 Besucher