php.de

Zurück   php.de > Webentwicklung > PHP-Fortgeschrittene

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 29.10.2010, 20:12  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.268
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard Binärcode auslesen

Hallo,

ich habe folgenden Codeschnipsel und würde ihn gerne verstehen:
PHP-Code:
<?php
    
private function parseKeyVal($string, &$numByte) {
        
$one unpack("C",substr($string,$numByte,1)); 
        
$one $one[1];
        
$retVal $one 0x7F;
        
$shift 1;
        
$numByte++;
        while ((
$one 0x80) > 0) {
            
$one unpack("C",substr($string,$numByte,1)); 
            
$one $one[1];
            
$retVal = (($one 0x7F) << $shift*7) | $retVal;
            
$shift++;
            
$numByte++;
        }
        return 
$retVal;
    }
?>
$string ist der Inhalt einer Binärdatei, $numByte der aktuelle "Pointer". Genau genommen geht es um das Auslesen von MPQ-Dateien, auf denen StarCraft 2 Replays basieren Dieser Teil ist nun aus der "Header User Data" zum Auslesen eines Schlüsselwertes.

Der Aufruf erfolgt über:
PHP-Code:
<?php
while ($fp < ($uDataSize $uDataStart)) {
    
$key unpack("C2",self::readBytes($this->fileData,$fp,2));
    
$value $this->parseKeyVal($this->fileData,$fp);
    if (
$this->debug)
        
$this->debug(sprintf("User header key: %02X %02X value: %d",$key[1],$key[2],$value));
    if (
$loop == 0) {
        switch (
$key[1]) {
            case 
0x02// major version
                
$this->verMajor $value 2;
                break;    
            case 
0x04// minor version
                
$versiontemp1 $value 2;
                break;
            case 
0x06// minorer? version
                
$versiontemp2 $value 2;
                break;
            case 
0x08;
                
$this->build $value 2;
                
$loop++;
                break;
            default:
        }
    }
    if (
$loop == 1) {
        switch (
$key[1]) {
            case 
0x06:
                
$this->gameLen ceil($value 32);
                break;
            default:
        }
    }
}
?>
Ich baue mir das ganze aus Spass nach, das Original sind mehrere Internetquellen (z.B. noch diese) und diese Klasse: phpsc2replay.

0x02 ist der Schlüssel für die Majorversion des Replays (oder der Anwendung), 0x04 der Schlüssel der Minorversion, 0x06 und 0x08 weitere Unterversionen. Hier der Hexcode des Abschnitts:
Code:
02 02 09 02 04 09 00 06 09 02 08 09 86 FD
Mir fehlt da etwas das Verständnis binärer Speicherung. Der 2. Codeschnipsel liest also 2 Byte ein und danach die variable (?) Länge des Werte (-> parseKeyVal). Was hier passiert entzieht sich mir. Ich lese den nächsten Byte, was 0x02 (Edit: achso ne 0x09) wäre und verunde mit 0x7F also 01 11 11 11.

Das ganze ist Little-Endian. Ist 0x02 also 00 01 00 00 oder 00 00 00 01? Wozu das ganze? Kann jemand aushelfen? Wird bei Little-/Big-Endian 8-Bitweise eingelesen?

Was shift macht ist mir auch klar (glaube ich), aber der Sinn dahinter ergibt sich mir nicht, warum nicht gleich einen Wert (numerisch) ablegen als INT32 und entsprechend Bytes reservieren. Warum dieses verunden, verordern und shiften?
__________________
"Nuschel ich?" - "Was?"

Geändert von Chriz (29.10.2010 um 20:20 Uhr).
Chriz ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 29.10.2010, 22:18  
Erfahrener Benutzer
 
Registriert seit: 04.08.2010
Beiträge: 287
PHP-Kenntnisse:
Fortgeschritten
zwutz wird schon bald berühmt werden
Standard

so wie ich das sehe, hast du einen zwei Byte großen Key (wovon aber nur das erste(?) Byte relevant ist), der zuerst ausgelesen wird.

Der obere Codeteil liest dann solange in der Datei weiter, bis er einen Wert kleiner 0x80 findet, mindestens aber ein Byte, und liefert das als Wert zurück

little endian heißt, dass das niederwertigeste Byte zuerst drankommt.
0x02 ist aber immer 00000010. Nur, wenn du zwei Bytes hast, merkst du einen Unterschied.

Es geht einfach darum, welches Byte du beim einlesen zuerst bekommst. Bei little endian das lsb, bei big endian das msb (least/most significant byte) (ja, ich weiß, die abkürzung wird eigentlich für die bits verwendet, aber "das am wenigsten signifikante Byte" klingt einfach kacke)

-edit-

kannst du mal die debug-ausgabe posten? Ich wundere mich gerade, warum auf $key[1] und $key[2] zugegriffen wird, und nicht 0/1

-edit2-

vielleicht die obere Funktion mal im Detail:

PHP-Code:
<?php
    
private function parseKeyVal($string, &$numByte) {
        
$one unpack("C",substr($string,$numByte,1)); // erstes Byte nehmen
        
$one $one[1]; // scheinbar liefert unpack im index 0 nicht das, was erwartet wird. Kenn die Funktionsweise leider nicht
        
$retVal $one 0x7F// interessant sind nur die letzten 7 bit. Bit 8 scheint lediglich ein Indikator zu sein, dass es sich um einen Wert und keinen Key handelt
        
$shift 1;
        
$numByte++;
        while ((
$one 0x80) > 0) { // solange bit 8 gesetzt ist
            
$one unpack("C",substr($string,$numByte,1)); // nächstes Byte einlesen
            
$one $one[1];
            
$retVal = (($one 0x7F) << $shift*7) | $retVal// byte nehmen (wobei bit 8 wieder ignoriert wird), um 7 bit nach rechts schieben und den bisherigen Wert dranhängen
            
$shift++;
            
$numByte++;
        }
        return 
$retVal;
    }
?>

Geändert von zwutz (29.10.2010 um 22:39 Uhr).
zwutz ist offline   Mit Zitat antworten
Alt 29.10.2010, 22:27  
Erfahrener Benutzer
 
Benutzerbild von Sonic
 
Registriert seit: 31.05.2010
Beiträge: 151
PHP-Kenntnisse:
Fortgeschritten
Sonic ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Für was braucht man sowas denn?

LG Sonic
Sonic ist offline   Mit Zitat antworten
Alt 29.10.2010, 22:43  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.268
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard

Hallo zwutz,

danke für die Info, ähm ja 0x02 ist natürlich dez. 2 und damit 10 binär. unpack() liefert einen Array, dessen Key mit 1 beginnt soweit ich weiß.

Ich stell mir halt die Frage, wozu das ganze, das Format scheint mir unsinnig zu sein, kann aber auch daran liegen, dass ich nicht aus der C++ Ecke komme.

@Sonic: Das sind eben StarCraft 2 Replays in Binärformat. Ist nur ein Spassprojekt.
__________________
"Nuschel ich?" - "Was?"
Chriz ist offline   Mit Zitat antworten
Alt 29.10.2010, 23:01  
Erfahrener Benutzer
 
Registriert seit: 04.08.2010
Beiträge: 287
PHP-Kenntnisse:
Fortgeschritten
zwutz wird schon bald berühmt werden
Standard

nun, der Grund wird folgender sein

man will key-value-paare abspeichern. Da der Wert aber variabel sein soll, kann nicht einfach mit festen Offsets gearbeitet werden, also muss man sich was neues überlegen, wie man das trennt.
Da die Keys eine wohl definierte Menge sind, kann man deren Länge gut auf 2 Byte festsetzen. Der Wert besteht immer aus einem Kontrollbit und dem eigentlichen Inhalt. Beim ersten Byte des Wertes ist dieses Bit noch egal, ab dann muss es gesetzt sein, damit dieses byte zum Wert dazukommt. Wenn nicht, ist man beim nächsten Key angelangt

Zugegeben eine etwas sonderbare Konstellation, aber bei variablen Wert-Breiten muss man sich nunmal was einfallen lassen
zwutz ist offline   Mit Zitat antworten
Alt 30.10.2010, 13:09  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.268
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard

Achso, das erste Bit legt fest, ob die folgenden sieben einen Wert darstellen und die werden aneinandergehängt?!

Edit: Komisch heut morgen beim Aufwachen hab ichs kapiert.
__________________
"Nuschel ich?" - "Was?"

Geändert von Chriz (30.10.2010 um 13:12 Uhr).
Chriz ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Parameter aus Url auslesen lzenz PHP Tipps 2010 6 27.05.2010 00:35
[Erledigt] preparedStatement auslesen funktioniert nicht ?! Raidri PHP Tipps 2009 11 02.11.2009 09:21
[Erledigt] Anzahl der Zeilen auslesen ( MySQL ) errox Datenbanken 13 18.02.2009 16:07
Scriptsuche Formular auslesen und verschicken Atsinganos Scriptbörse 8 21.01.2009 12:54
[Erledigt] variable Postvariablen auslesen carsten PHP Tipps 2008 2 30.10.2008 16:20
Ordner auslesen und während des auslesen sortieren Dooki PHP Tipps 2008 6 14.05.2008 17:50
Vom Browser verschickte Daten auslesen und anzeigen? andy32 PHP Tipps 2008 3 22.08.2007 18:33
[Erledigt] gelöst: Tabelle auslesen -&amp;amp;amp;amp;gt; Gleiche Einträge nur 1 Mal Datenbanken 3 31.03.2006 01:44
Textdatei auslesen, aber ohne Komentare HSFighter PHP Tipps 2006 31 23.02.2006 10:07
[Erledigt] bestimmte ID's auslesen als array PHP Tipps 2007 2 31.10.2005 20:23
Daten eintragen und auslesen Rettungsdackel Datenbanken 0 14.09.2005 16:29
Daten aus Pw-Geschütztem bereich auslesen PHP-Fortgeschrittene 2 26.08.2005 15:27
auslesen und nochmals auslesen?! $$$ ThiKool $$$ PHP Tipps 2005 23 10.03.2005 19:43
[Erledigt] Daten von anderer Homepage auslesen PHP Tipps 2004-2 5 02.12.2004 18:49

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
binärcode lesen, binärcode tabelle, binärcode auslesen, binärcodetabelle, binär code auslesen, binär code lesen, 8 bit binärcode, dualcode tabelle, binärcode schlüssel, aus hex 11 einzelne bits auslesen shift c, binärcode php, php byte auslesen, 7 bit binärcode, php binärcode, phpsc2replay, php string bitweise einlesen, \binärcode auslesen, binärcode einlesen, ersten bytes lesen php, binärcodes lesen

Alle Zeitangaben in WEZ +2. Es ist jetzt 01:12 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum