Struktura *.torrent souboru

November 19, 2006 on 10:39 am | In Programing |

Pro všechny lidi, které to zajímá stejně jako mě, ale nechtělo se jim číst nudné specifikace…

Bencoding

Ne neděste se. Není to žádný můj nesmyslný výmysl, ale způsob kódování dat v torrentech. V podstatě se nejedná o nic složítého a s odstupem času musím přiznat, že toto kódóvání značně ulehčuje práci při parsování torrentu. Torrent je textový soubor ovšem data jsou jako by na jednom řádku - dalo by se řící, že je to proud znaků.

Nejzákladnější jednotkou je textový úsek. Aby ho člověk (počítač) mohl odlišit od dalšího textu, tak je zapsán jako délka:text (pro příkladh 6:jarcec znamená, že se jedná o 6 znakový text “jarcec”). Další entity se přidávají hned za tento text, takže chci li za sebe napsat dvě textové entity, tak to provedu takto: “10:created by6:jarcec”. Všimněte si prosím, že délka řetězce není délka slova, ale celé entity a klidně může obsahovat i mezeru (tedy více než jedno slovo) a dokonce může obsahovat i znak nového řádku - napřiklad uvnitř sha1 hashe.

Druhým typem jsou celá čísla. Zde je prvním znakem znak ‘i’ (105 v ASCII) následovaný hodnotou (eventuálně se znaménkem ‘-’ pro záporná čísla) a ukončený znakem ‘e’ (101 v ASCII). Tedy “i65e” znamená číslo “65″, i-30e znamená číslo “-30″. Zápis “i0003e” již je nesprávný a neměl by být brán jako zápis čísla 3. Ovšem na druhou stranu i0e je zcela v pořádku! Co se týče velikosti načítaného čísla, tak by se mělo vlést do 64bitového integeru u enormě velkých torrentů.

Dalším typem je list. Dalo by se říci, že se jedná pole - tedy výčet prvků. Jenže na rozdíl od pole v programovacích jazycích, zde nemusí platit, že se jedná o pole stejných datových typů. Tedy v listu můžou být jako textové entity tak i čísla nebo dokonce i další listy!. Zápis je ‘l’ (108 v ASCII), výčet prvků a vše je ukončeno znakem ‘e’ (101 v ASCII). Pro příklady “l5:opera8:konqueror2:IEli5ei30ee7:firefoxe” znamená tento list [’opera’, ‘konqueror’, ‘IE’, [5, 30], ‘firefox’]. Doufám, že zápisu je zdřejmé jak se pracuje s listy.

Poslední možnou entitou je dictionary (záměrně nepřekládám). Je to dvojice klíč-hodnota. Podobně jako list se dictionary zapisuje jako ‘d’ (100 v ASCII), klíč, výčet prvků a zakončující ‘e’ (101 v ASCII). Počet vnitřních entit je vždy párový: “d6:author6:jarcec4:datei11550ee”. I zde platí, že se v dictionary může oběvit i list: “d6:optionl3:yes2:no6:cancelee”, zde tedy hodnotě “option” náleží celý list [’yes’, ‘no’, ‘cancel’].

Struktura torrentu:

Celý obsah torrentu je bencodován (pěkné české slovo, že? :-) ) a je uložen v dictionary (tedy v páru klíč - hodnota). Text by měl být uložen v UTF-8. Seznam přípustných hlaviček a jejich vysvětlení:

  • announce: URL strackeru, uloženo jako string samozdřejmě
  • announce-list: (volitelné) rozšíření původního protokolu, které zachovává zpětnout kompatibilitu. V případě, že je v torrentu uvedena tato hlavička a klient je s ní kompatibilní, tak by měl ignorovat trackera v announce a řídít se pouze touto hlavičkou. Je to list listů a pro jeho přesnou specifikaci Vás budu muset odkázat někam jinam :-( .
  • creation date: datum vytvoření torrentu zapsané jako počet sekund od 1.1.1970 (UNIX epoch). Jedná se tedy o integer.
  • comment: (volitelné) komentář k torrentu, dle specifikace neomezen délkou
  • created by: (volitelné) jméno a verze programu, která tento torrent vytvořila
  • info: jedná se o dictionary popisující soubory, které torrent obsahuje (informace o nich)
  • piece length: velikost každé části torrentu v bytech. Samozdřejmě, že poslední část má menší velikost.
  • pieces: řetězec x těsně po sobě jdoucích 20 bytových sha1 hashů. vždy jeden pro každou část (piece). Počet částí (pieces) lze tedy získat jako délku totoho řetezce vydělené 20ti.
  • private: (volitelné), hodnotou je integer. Obsahuje-li hodnotu 1, tak se jedná o soukromý torrent a uživatel by neměl mít možnost přidávat další trackery. Pro další info Vás bohužel opět budu muset odkázat na stryčka googla.
  • name: jméno souboru nebo složky (v případě více souborového torrentu)
  • length: pouze v případě jednosouborového torrentu, obsahuje velikost souboru v bytech
  • md5sum: (volitelný) a pouze v případě jednosouborového torrentu, md5sum stahovaného souboru
  • files: pouze v případě více souborového torrentu. Hodnotou je list dictionary. Každé dictionary v tomto listu obsahuje informace o jednom souboru a má tyto hlavičky:
  • length: velikost souboru
  • md5sum: (volitelné) md5sum souboru
  • path: list adresářů a (jako poslední entita) jména vlastního souboru. Pokud je soubor uložen jako /slozka1/slozka2/soubor.avi, tak by byl zapsán takto: 4:pathl7:slozka17:slozka210:soubor.avie. Tedy jako list stringů [’slozka1′, ’slozka2′, ’soubor.avi’].

TorLi

V rámci studa jsem si vytvořil program, který parsuje torrent soubor a vytiskne obsah jeho důležitých hlaviček. K mání jsou jak zdrojové kódy tak i binárka (ELF). Kompilaci provedete příkazem ’scons’ a ve složce Vám vznikne nová binárka “TorLi”. Zkoušel jsem všechny torrenty co mám na disku a nenašel jsem žádný, se kterým by program měl problémy, ale podaří-li se Vám takový torrent najít, tak mi ho prosím pošlete a já se podívam kde mi to vázne ;-)

Off topic: Dokážete si  představit, že by jste museli psát podobný parser v pascalu? Ja tedy ne…

No Comments yet »

RSS feed for comments on this post. TrackBack URI

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

Powered by WordPress with Pool theme design by Borja Fernandez.
Entries and comments feeds. Valid XHTML and CSS. ^Top^