Skip to content
jrudolph edited this page Sep 24, 2012 · 3 revisions

Die planBZ Datei enthält die Fahrpläne pro Station. Im Gegensatz zu den meisten anderen Dateien, sind die Einträge in dieser Datei verschlüsselt und komprimiert gespeichert.

Table of Contents

Übersicht

  • Header
  • Index
  • Daten

Header

Offset Typ Länge Feld Beschreibung
0 u2 2 Headerlänge
2 u2 2 Major-Version
4 u2 2 Minor-Version
6 date 4 Erzeugungsdatum
10 u4 4 Gesamtanzahl von Fahrplaneinträgen
14 6 Unbekannt
20 u4 4 Anzahl von Einträgen im Index
...

Index

Der Index ist ein Array, das für jede Station den Offset und die Anzahl von Untereinträgen enthält. Jeder Eintrag ist 6 Bytes lang. Der Index beginnt direkt nach dem Header, also an Position Headerlänge. Die Offsets steigen monoton an, wobei einige Offsets 0xffffffff sein können.

Der absolute Offset eines Eintrags für die Station mit ID s ist also Headerlänge + 6 * s

Offset Typ Länge Feld Bemerkung
0 u4 4 Absoluter Offset vom Dateianfang aus gerechnet zum Eintrag 0xffffffff, wenn Anzahl der Einträge = 0
4 u2 2 Anzahl von Untereinträgen

Daten

Der Datenblock beginnt nach dem Index. Die Länge der Einträge ist variabel. Jeder Eintrag ist verschlüsselt mit der jeweiligen Stations-ID. Die absolute Position wird bestimmt durch Nachschlagen im Index. Ein Eintrag läuft bis zum nächsten (gültigen) Eintrag im Index.

Verschlüsselung

Ein Keystream der selben Länge wie die Daten wird wie folgt erzeugt:

key[0] = stationId
key[i] = (key[i-1] * 0x0C95 + 1) & 0xffff

Die entschlüsselten Daten (dec) werden aus den verschlüsselten Daten (enc) wie folgt erzeugt:

dec[i] = enc[i] XOR (key[i+1] & 0xff)

Datenstream

Die Einträge im Datenstream sind Tupel der Form (trainId, arrivalTime, departureTime). Ankunfts- und Abfahrtszeiten sind jeweils in Minuten nach Mitternacht angegeben.

Es werden immer abwechselnd eine trainId und eine Ankunfts-/Abfahrtszeit vom Stream gelesen, wobei manchen Einträgen auch den letztgelesenen Eintrag referenzieren. Auch der erste Eintrag kann einen vorgehenden Eintrag referenzieren, dieser wird dann als (trainId = 0, arrival = 0, departure = 0) angenommen.

trainId Format

Flags im ersten Byte entscheiden wieviele Bytes für die trainId verbraucht werden. Die Bytes der trainId werden als BIG_ENDIAN gelesen und der Flagteil (0xe0) im ersten Byte wird 0 gesetzt.

Bitmaske Anzahl Bytes Interpretation
0x80 0 trainId = lastTrainId + 1, das Byte gehört schon zu den Zeiten
0x60 2 trainId = lastTrainId + wert
0x40 1 trainId = lastTrainId + wert
0x20 1 trainId = lastTrainId + wert, es folgen keine Zeiten, sondern die letzten Zeiten werden übernommen und es wird direkt der nächste trainId Eintrag gelesen.
sonst (d.h. alle Bits im Bereich 0xe0 sind 0) 4 trainId = wert

Zeiten Format

Ankunfts-/Abfahrtszeiten liegen normalerweise im Bereich 0 - 1440 (ein Tag hat 1440 Minuten). Man benötigt also im Normalfall 11 Bits um eine solche Zahl absolut zu speichern. Häufig wird allerdings auch die Abfahrtszeit relativ zur Ankunftszeit gespeichert.

Zuerst wird die Ankunftszeit gelesen, Flags im ersten Byte geben die Kodierung und weitere Informationen an.

Bitmaske Anzahl Bytes Bitschema Interpretation
0xf8 2 1111 1ddd dddd dddd Es gibt keine Ankunftszeit. Die verbleibenden Bits (0x07ff) geben die absolute Abfahrtszeit an.
0xf0, 0x08 nicht gesetzt 2 1111 0aaa aaaa aaaa Es gibt keine Abfahrtszeit. Die verbleibenden Bits (0x07ff) geben die absolute Ankunftszeit an.
0x80 2 1ddd daaa aaaa aaaa Ankunfts-/Abfahrtszeit werden wie folgt kodiert: die 11 a-Bits, sind die absolute Ankunftszeit. Die 4 d-Bits geben die Abfahrtszeit relativ dazu an.
0x80 nicht gesetzt 2 0wxy zaaa aaaa aaaa 11 a-Bits sind absolute Ankunftszeit. w-z sind flags. w bedeutet, dass die Zeit nicht angezeigt werden soll, weil kein Ausstieg möglich ist. x ist unklar (kommt das vor?), y unklar (wurde selten bei Schlafwägen beobachtet), z unklar (häufig, vielleicht "nicht täglich"?)

Wenn 0x80 nicht gesetzt war, folgt die Abfahrtszeit:

Bitmaske Anzahl Bytes Bitschema Interpretation
0x80 1 1xdd dddd 6 d Bits geben relative Abfahrtszeit an, Flag x bedeutet, "Kein Zustieg möglich"
sonst 2 0wxy zddd dddd dddd 11 d Bits geben Abfahrtszeit an, Flag w bedeutet, "Kein Zustieg möglich", restliche Flags unklar. Wenn Abfahrtszeit == 0x07ff, dann gibt es keine Ankunftszeit, aber Flags.