pack() Funktion anhand eines Beispiels

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • pack() Funktion anhand eines Beispiels

    Hi

    bis jetzt hatte ich mit pack() noch nichts zu tun und verstehe leider nichts. Komme dementsprechend auch keinen Millimeter weiter.

    Ich habe hier ein Dokumentation in der folgendes steht:
    Code:
    This 40-bit field contains the start time of the event in Universal Time, Co-ordinated (UTC) and Modified
    Julian Date (MJD) (see annex C). This field is coded as 16 bits giving the 16 LSBs of MJD followed by 24 bits coded as
    6 digits in 4-bit Binary Coded Decimal (BCD). If the start time is undefined (e.g. for an event in a NVOD reference
    service) all bits of the field are set to "1".
    EXAMPLE 1: 93/10/13 12:45:00 is coded as "0xC079124500".
    Ich versuche das Beispiel nachzuvollziehen und zu codieren. Aber ich komme nicht mal in die Nähe aus "93/10/13 12:45:00" das entsprechende Ergebnis zu erzielen.

    Kann mir bitte jemand erklären wie das gemacht wird?

  • #2
    (see annex C)
    Was steht dort?

    Kommentar


    • #3
      Zitat von Akira Beitrag anzeigen
      Code:
      EXAMPLE 1: 93/10/13 12:45:00 is coded as "0xC079124500".
      Aber ich komme nicht mal in die Nähe aus "93/10/13 12:45:00" das entsprechende Ergebnis zu erzielen.
      Na die Uhrzeit 12:45:00 solltest du da ja relativ leicht wiederfinden, wenn du mal scharf hinschaust – 124500 am Ende des Wertes.

      Modified Julian Date ist das „normale“ Julianische Datum, minus 2400000.5 – siehe Wikipedia, https://en.wikipedia.org/wiki/Julian_day#Variants

      cal_to_jd gibt dir das Julianische Datum, für den 13.10.1993 ist das 2449274, in MJD also 49273.5.

      Und wenn du auf diese Zahl mal dechex() anwendest, erhältst du: c079
      I don't believe in rebirth. Actually, I never did in my whole lives.

      Kommentar


      • #4
        Meine Konzentration ist in letzter Zeit nicht besonders gut. Das die Uhrzeit einfach so angehängt wird habe ich nicht gesehen.

        Weiters habe ich jetzt die ganze Zeit versucht das Datum aus dem Julianischen Kalender in einen "Julian Day Count" zu verwandeln, funktioniert natürlich nicht.
        Wenn ich vom Gregorianischen Kalender ausgehe klappt es plötzlich

        Viellen Dank. Mal sehen ob ich den Rest vielleicht selbst schaffe

        Kommentar


        • #5
          Jetzt bin ich ja wirklich weitergekommen

          Allerdings stehe ich vor einem neuen Problem. mit pack() kann ich nicht direkt 24 bit oder 40 bit packen.
          Kann ich das irgendwie teilen (24 bit = 3x8bit) oder ähnliches?

          Kommentar


          • #6
            Was für ein Format brauchst du denn letztendlich?

            Das Beispiel zeigt ja nur einen Hex-String, bzw. eine Zahl in hexadezimaler Notation.
            I don't believe in rebirth. Actually, I never did in my whole lives.

            Kommentar


            • #7
              Zitat von h3ll;
              Was steht dort?
              Neben einer wenig nützlichen Grafik hauptsächlich Formeln, die zeigen, wie man zwischen beiden Datums-Formaten hin- und herkonvertiert: Auf den Seiten 71 + 72. [color=#999999]Aber wenn du da jetzt nachschaust, verdirbst du dir den ganzen Ratespaß. [/color]

              Die aktuelle Version gibts unter Work Programme - Work Item Detailed Report. Leider fehlen dort die schönen Formeln.

              Zitat von wahsaga;
              Was für ein Format brauchst du denn letztendlich?
              Vermutlich Timestamps für EPG.

              Zitat von Akira Beitrag anzeigen
              Jetzt bin ich ja wirklich weitergekommen

              Allerdings stehe ich vor einem neuen Problem. mit pack() kann ich nicht direkt 24 bit oder 40 bit packen.
              Kann ich das irgendwie teilen (24 bit = 3x8bit) oder ähnliches?
              Kannst du. Pack() kann Bytes einzeln setzen. Bspw.: so:
              PHP-Code:
              pack('CCC'$var0$var2$var3); 
              Allerdings spricht der Informationsfetzen, den du zitierst, von BCD-Kodierung. Das sind Zahlen von 0 bis 10 in "halben Bytes", keine ganzen. Schau dir zum Vergleich und zur Ideen-Findung mal an, wie das in Perl gelöst wird. Perls pack-Funktion (siehe auch) funktionert ähnlich wie die in PHP.

              Update: Wenn man die Uhrzeit passend formatiert aus einem DateTime-Objekt herauszieht, kann man pack() direkt damit füttern:
              PHP-Code:
              pack('nH6'0xffff $mjdaycount$dt->format('His')); 
              Das ist zwar nicht ganz die feine englische Art, weil 'H' eigentlich dafür da ist, Hex-Ziffern (0-9,A-F) in Halfbytes zu quetschen, aber es funktioniert hier, weil die Ziffern in korrekten Tageszeitangaben im entsprechenden Rahmen bleiben.

              'n' belegt hier zwei Bytes (16 Bit).
              'H6' nimmt sich 6 halbe Bytes, also 3 ganze (24 Bit)

              PHP: pack - Manual

              Den Rückgriff auf Formeln zur Berechnung des MJD kann man sich auch sparen, wenn man das Epochen-Datum des MJD kennt ("1858-11-17T00:00:00"):
              PHP-Code:
              $epoch = new DateTime('1858-11-17T00:00:00', new DateTimeZone('UTC'));
              $datetime = new DateTime(...);
              $mjdaycount $datetime->diff($epoch)->days
              Dann gibts auch keine Verwirrung mit den Kalendertypen, denn DateTime und DateInterval (das von ->diff() geliefert wird) können nur "gregorianisch".

              PHP: DateTime - Manual
              PHP: DateTime::format - Manual
              PHP: date - Manual (erklärt die Format-Templates)
              PHP: DateTime::diff - Manual
              PHP: DateInterval - Manual
              Zuletzt geändert von fireweasel; 15.07.2015, 15:46. Grund: typo + ergänzungen
              Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

              Kommentar


              • #8
                Danke dir für deine Mühe, fireweasel.

                Hab deinen Beitrag mal überflogen, hab aber erst in ein paar Wochen wieder Zeit hier weiterzumachen.

                Kommentar


                • #9
                  Nochmals Danke für deine Mühe fireweasel.

                  Aber ich begrabe das Projekt zum zweiten Mal. Diesmal endgültig. Ich habe einfach nicht die Geduld und die Zeit mich da reinzudenken. Vielleicht werde ich alt . Genug gejammert.

                  Gibt es eine php Klasse die ich nur mehr einbinden muss? Ja ich habe deinen Link gesehen und heruntergeladen. Aber ich habe nicht geschafft diese perl Klasse zum Laufen zu bekommen. Habe mich mit perl auch noch nie beschäftigt und werde damit auch nicht anfangen.

                  Wenn es keine fertige PHP Klasse gibt habe ich halt Pech gehabt und werde darauf verzichten.

                  Kommentar


                  • #10
                    Zitat von Akira Beitrag anzeigen
                    Ja ich habe deinen Link gesehen und heruntergeladen. Aber ich habe nicht geschafft diese perl Klasse zum Laufen zu bekommen. Habe mich mit perl auch noch nie beschäftigt und werde damit auch nicht anfangen.
                    Das Perl-Modul war nur als Inspirationsquelle gedacht (weil es in PHP derzeit nichts vergleichbares gibt). Es kodiert und dekodiert EIT-Strukturen (bspw. die in MPEG-Streams oder -Dateien) und nutzt dazu u.A. pack() und unpack(). Beide Perl-Funktionen waren das Vorbild, nach dem PHP's pack() und unpack() geschaffen wurden. Aber nicht so wichtig.

                    Mir ist noch immer nicht ganz klar, worauf du eigentlich hinauswolltest:
                    - die EIT-Struktur kodieren und dekodieren?
                    - pack() und unpack() verstehen lernen?
                    Ersteres geht auch ohne letzeres, wie du in diesem Thread hier an wahsagas Beiträgen gut sehen kannst. Wenn dir diese Vorgehensweise mehr liegt, als dich in komische Format-Codes einzuarbeiten, ist das vollkommen in Ordnung.

                    Zitat von Akira Beitrag anzeigen
                    Gibt es eine php Klasse die ich nur mehr einbinden muss?
                    Ich hatte da was gebastelt, weiß aber nicht, ob es deinen Ansprüchen genügt:
                    PHP-Code:
                    /*
                    Encode + decode the start_time structure in Event Information Tables as given in
                    http://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.14.01_60/en_300468v011401p.pdf
                    ETSI EN 300 468 V1.14.1 (2014-05) Section 5.2 Table definitions (page 29)
                    */
                    class EitStartTime {
                        
                    /// get the epoch (base date) for the MJD
                        /// return obj(DateTime::)
                        
                    static function epoch() {
                            static 
                    $epoch null;
                            if (
                    null === $epoch) {
                                
                    $epoch = new DateTime('1858-11-17T00:00:00', new DateTimeZone('UTC'));
                            }
                            return clone 
                    $epoch;
                        }

                        const 
                    UNDEFINED "\xff\xff\xff\xff\xff"// all bits set

                        /// get start_time from the EIT table
                        /// return str() binary data
                        
                    static function encode(DateTimeInterface $dt null) {
                            if (
                    null === $dt) {
                                return 
                    self::UNDEFINED;
                            }
                            return 
                    pack(
                                
                    'nH6',
                                
                    0xffff $dt->diff(self::epoch())->days// truncated (c)mjd
                                
                    $dt->format('His'// time of day
                            
                    );
                        }

                        
                    /// build DateTime object from encoded binary string
                        /// return obj(DateTime::)|null()
                        
                    static function decode($packed) {
                            if (
                    self::UNDEFINED === $packed) {
                                return 
                    null;
                            }
                            if (
                    strlen($packed) < 5) {
                                throw new 
                    Exception('binary string must contain at least 5 bytes');
                            }
                            
                    $struct = (object) unpack(
                                
                    'ndays/H*time'// unpack formats suck
                                
                    substr($packed05)
                            );
                            
                    $dt self::epoch(); // cloned
                            
                    if (
                                !
                    $dt->modify('+' $struct->days 'days') || // add days since MJD epoch
                                
                    !$dt->modify('T' $struct->time// set timeofday
                            
                    ) {
                                throw new 
                    Exception('invalid binary string given');
                            }
                            return 
                    $dt;
                        }

                    ::encode() macht aus einem DateTime- oder DateTimeImmutable-Objekt einen Binärstring, den man prinzipiell direkt in die EITable schreiben kann. Wenn man es mit dem Wert NULL füttert, liefert es den speziell kodierten ::UNDEFINED-String.

                    ::decode() wandelt den Binärstring wieder in ein DateTime-Objekt. Aus dem speziellen ::UNDEFINED-String macht es NULL.

                    Ein einfacher Test mit dem üblichen Beispiel-Zeitstempel und zwei Werten, die als ::UNDEFINED erkannt werden sollen, hat zumindest bei mir funktioniert:

                    PHP-Code:
                    $tests = array (
                        
                    '1993-10-13T12:45:00+00:00',
                        
                    null,
                        
                    '-'
                    );

                    foreach (
                    $tests as $test) {
                        try {
                            
                    $dt = new DateTime($test);
                        }
                        catch (
                    Exception $ex) {
                            
                    $dt null;
                        }
                        
                    $enc EitStartTime::encode($dt);
                        
                    var_dump(current(unpack('H*'$enc))); // als Hex-String
                        
                    $dec EitStartTime::decode($enc);
                        
                    var_dump($dec); // als Datums-Objekt oder NULL
                        //Error::writefln('enc: %S dec: %S', current(unpack('H*', $enc)), $dec);

                    Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

                    Kommentar


                    • #11
                      Ich bin es nicht gewöhnt das mir solche Code Schnippsel vorgebetet werden

                      Ich mache trotzdem nicht weiter. Ist mir zu Zeitaufwändig. Dieses bit-weise packen hab ich noch nie gemacht und ich habs immer noch nicht vollsändig verstanden....

                      Worauf ich hinaus will?
                      Ich habe eine Film Datenbank. Erstellt mit PHP. Nicht gerade die Programmiersprache (Skriptsprache) der Wahl aber die einzige die ich kann. Außerdem stand da (vor ca. 4 Jahren) der Spaß am coden im vordergrund.

                      Jetzt wollte ich in meine Film Datenbank noch die Möglichkeit implementieren Norm-konforme .eit Dateien zu erstellen damit die enigma2 Box mir eine Inhaltsanagabe der Aufnahmen anzeigt. Mit Short Description, Extendes Description usw.

                      Aber wie gesagt, ist es mir neben meinem Vollzeitjob und Familie einfach zu zeitaufwändig. Bis ich mir da alles was ich brauche erarbeitet habe vergehen Tage...

                      Kommentar

                      Lädt...
                      X