-
Notifications
You must be signed in to change notification settings - Fork 11
Planbz
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.
- Header
- Index
- Daten
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 | |
... |
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 |
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.
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)
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.
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
|
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. |