.ZIP-bestanden zijn archieven waarin meerdere bestanden kunnen worden opgeslagen. Met ZIP kunnen bestanden worden gecomprimeerd met behulp van verschillende methoden, maar een bestand kan ook gewoon worden opgeslagen zonder het te comprimeren. Elk bestand wordt afzonderlijk opgeslagen, zodat verschillende bestanden in hetzelfde archief met verschillende methoden kunnen worden gecomprimeerd. Omdat de bestanden in een ZIP-archief afzonderlijk worden gecomprimeerd, is het mogelijk ze uit te pakken, of nieuwe bestanden toe te voegen, zonder compressie of decompressie op het gehele archief toe te passen. Dit in tegenstelling tot het formaat van gecomprimeerde tar-bestanden, waarvoor een dergelijke random-access verwerking niet goed mogelijk is.
Aan het eind van een ZIP-bestand wordt een directory geplaatst. Deze identificeert welke bestanden zich in de ZIP bevinden en geeft aan waar in de ZIP dat bestand zich bevindt. Hierdoor kunnen ZIP-lezers de lijst met bestanden laden zonder het hele ZIP-archief te lezen. ZIP-archieven kunnen ook extra gegevens bevatten die geen verband houden met het ZIP-archief. Zo kan van een ZIP-archief een zelfuitpakkend archief worden gemaakt (een toepassing die de daarin opgenomen gegevens decomprimeert), door de programmacode aan een ZIP-archief toe te voegen en het bestand als uitvoerbaar te markeren. Het opslaan van de catalogus aan het eind maakt het ook mogelijk een gezipt bestand te verbergen door het toe te voegen aan een onschadelijk bestand, zoals een GIF-afbeeldingsbestand.
Het .ZIP-formaat gebruikt een 32-bits CRC-algoritme en bevat twee kopieën van de directorystructuur van het archief om meer bescherming te bieden tegen gegevensverlies.
StructureEdit
Een ZIP-bestand wordt correct geïdentificeerd door de aanwezigheid van een record voor het einde van de centrale directory die zich aan het einde van de archiefstructuur bevindt om het gemakkelijk toevoegen van nieuwe bestanden mogelijk te maken. Als het einde van centrale directory record een niet-leeg archief aangeeft, moet de naam van elk bestand of map binnen het archief worden gespecificeerd in een centrale directory ingang, samen met andere metadata over de ingang, en een offset in het ZIP-bestand, wijzend naar de werkelijke ingangsgegevens. Hierdoor kan een bestandslijst van het archief relatief snel worden uitgevoerd, aangezien niet het gehele archief hoeft te worden gelezen om de lijst van bestanden te zien. De ingangen in het ZIP-bestand bevatten deze informatie, ter redundantie, ook in een lokale header van het bestand. Omdat aan ZIP-bestanden bijlagen kunnen worden toegevoegd, zijn alleen bestanden geldig die aan het eind van het bestand in de centrale directory staan. Het scannen van een ZIP-bestand op lokale bestandsheaders is ongeldig (behalve in het geval van corrupte archieven), omdat de centrale directory kan verklaren dat sommige bestanden zijn verwijderd en andere bestanden zijn bijgewerkt.
Bij voorbeeld, we kunnen beginnen met een ZIP-bestand dat de bestanden A, B en C bevat. Bestand B wordt dan verwijderd en C bijgewerkt. Dit kan worden bereikt door gewoon een nieuw bestand C toe te voegen aan het einde van het oorspronkelijke ZIP-bestand en een nieuwe centrale directory toe te voegen waarin alleen bestand A en het nieuwe bestand C staan. Toen ZIP voor het eerst werd ontworpen, was het overbrengen van bestanden per diskette gebruikelijk, maar het schrijven naar schijven was zeer tijdrovend. Als je een groot zip-bestand had, mogelijk verspreid over meerdere schijven, en je hoefde maar een paar bestanden bij te werken, in plaats van alle bestanden te lezen en opnieuw te schrijven, zou het aanzienlijk sneller zijn om alleen de oude centrale directory te lezen, de nieuwe bestanden toe te voegen en dan een bijgewerkte centrale directory toe te voegen.
De volgorde van de bestandsvermeldingen in de centrale directory behoeft niet samen te vallen met de volgorde van de bestandsvermeldingen in het archief.
Elk bestand dat in een ZIP-archief wordt opgeslagen, wordt ingeleid door een lokale bestandsheader met informatie over het bestand, zoals het commentaar, de bestandsgrootte en de bestandsnaam, gevolgd door optionele “extra” gegevensvelden, en vervolgens de mogelijk gecomprimeerde, mogelijk gecodeerde bestandsgegevens. De “extra” gegevensvelden zijn de sleutel tot de uitbreidbaarheid van het ZIP-formaat. “Extra” velden worden gebruikt voor ondersteuning van het ZIP64 formaat, WinZip-compatibele AES encryptie, bestandsattributen, en hogere-resolutie NTFS of Unix bestandstijdstempels. Andere uitbreidingen zijn mogelijk via het “Extra”-veld. ZIP-tools moeten volgens de specificatie Extra velden die ze niet herkennen, negeren.
Het ZIP-formaat gebruikt specifieke “handtekeningen” van 4 bytes om de verschillende structuren in het bestand aan te duiden. Elk bestandsgegeven wordt gemarkeerd door een specifieke handtekening. Het einde van de centrale directory wordt aangegeven met een specifieke handtekening, en elke invoer in de centrale directory begint met de 4-byte handtekening van de centrale bestandsheader.
Er is geen BOF of EOF marker in de ZIP specificatie. Conventioneel is het eerste ding in een ZIP-bestand een ZIP-entry, die gemakkelijk kan worden geïdentificeerd door zijn lokale file header signature. Dit is echter niet noodzakelijkerwijs het geval, aangezien dit niet vereist wordt door de ZIP-specificatie – met name een zichzelf uitpakkend archief zal beginnen met een uitvoerbare bestandskoptekst.
Tools die ZIP archieven correct lezen, moeten scannen op de signatuur van het einde van de centrale maprecord, en vervolgens, indien van toepassing, op de andere, aangegeven, centrale maprecords. Zij moeten niet scannen op entries vanaf de top van het ZIP-bestand, omdat (zoals eerder vermeld in deze sectie) alleen de centrale directory aangeeft waar een bestand chunk begint en dat het niet is verwijderd. Scannen zou kunnen leiden tot valse positieven, aangezien het formaat niet verbiedt dat andere gegevens zich tussen chunks bevinden, noch dat bestandsgegevensstromen dergelijke handtekeningen bevatten. Hulpmiddelen die proberen gegevens uit beschadigde ZIP-archieven te herstellen, zullen het archief echter waarschijnlijk scannen op lokale bestandsheader-handtekeningen; dit wordt bemoeilijkt door het feit dat de gecomprimeerde grootte van een bestandschunk na de bestandschunk kan worden opgeslagen, waardoor sequentiële verwerking wordt bemoeilijkt.
De meeste handtekeningen eindigen met het korte gehele getal 0x4b50, dat is opgeslagen in little-endian volgorde. Als ASCII string is dit “PK”, de initialen van de uitvinder Phil Katz. Wanneer een ZIP-bestand dus in een tekstverwerker wordt bekeken, zijn de eerste twee bytes van het bestand gewoonlijk “PK”. (DOS, OS/2 en Windows zelf-uitpakkende ZIP’s hebben een EXE voor de ZIP en beginnen dus met “MZ”; zelf-uitpakkende ZIP’s voor andere besturingssystemen kunnen op vergelijkbare wijze worden voorafgegaan door uitvoerbare code voor het uitpakken van de inhoud van het archief op dat platform.)
De .ZIP-specificatie ondersteunt ook het verspreiden van archieven over meerdere bestandssysteem-bestanden. Oorspronkelijk bedoeld voor de opslag van grote ZIP-bestanden over meerdere diskettes, wordt deze functie nu gebruikt voor het verzenden van ZIP-archieven in delen via e-mail, of via andere transporten of verwijderbare media.
Het FAT-bestandssysteem van DOS heeft een tijdstempelresolutie van slechts twee seconden; ZIP-bestandsrecords bootsen dit na. Als gevolg daarvan is de ingebouwde tijdstempelresolutie van bestanden in een ZIP-archief slechts twee seconden, hoewel extra velden kunnen worden gebruikt om nauwkeuriger tijdstempels op te slaan. Het ZIP-formaat heeft geen notie van tijdzone, dus tijdstempels zijn alleen zinvol als bekend is in welke tijdzone ze zijn gemaakt.
In september 2007 heeft PKWARE een herziening van de ZIP-specificatie uitgebracht die voorziet in de opslag van bestandsnamen met UTF-8, waarmee eindelijk Unicode-compatibiliteit aan ZIP wordt toegevoegd.
BestandskoptekstenEdit
Alle multi-byte waarden in de koptekst worden opgeslagen in little-endian bytevolgorde. Alle lengtevelden tellen de lengte in bytes.
De header van een lokaal bestandEdit
Offset | Bytes | Description |
---|---|---|
0 | 4 | De signatuur van de header van een lokaal bestand = 0x04034b50 (te lezen als een little-endian getal) |
4 | 2 | Versie nodig om uit te pakken (minimum) |
6 | 2 | General purpose bit flag |
8 | 2 | Compressiemethode |
10 | 2 | Bestand laatste wijzigingstijd |
12 | 2 | Bestand laatste wijzigingsdatum |
14 | 4 | CRC-32 van ongecomprimeerde gegevens |
18 | 4 | gecomprimeerde grootte (of 0xffffffff voor ZIP64) |
22 | 4 | Gecomprimeerde grootte (of 0xffffff voor ZIP64) |
26 | 2 | Bestandsnaamlengte (n) |
28 | 2 | Extra veldlengte (m) |
30 | n | Bestandsnaam |
30+n | m | Extra veld |
Het extra veld bevat een verscheidenheid aan optionele gegevens, zoals OS-specifieke attributen. Het is verdeeld in chunks, elk met een 16-bit ID code en een 16-bit lengte. Voor ZIP64 bestaat er altijd ten minste één chunk (met ID-code 0001 en een grootte van 32 bytes), zie hieronder.
Dit wordt onmiddellijk gevolgd door de gecomprimeerde gegevens.
GegevensdescriptorEdit
Als de bit op offset 3 (0x08) van het veld met de algemene vlaggen is gezet, dan zijn de CRC-32 en de bestandsgrootte niet bekend wanneer de header wordt geschreven. De velden in de lokale header worden gevuld met nul, en de CRC-32 en grootte worden toegevoegd in een 12-byte structuur (optioneel voorafgegaan door een 4-byte signature) direct na de gecomprimeerde data:
Offset | Bytes | Description |
---|---|---|
0 | 0/4 | Optionele data descriptor signature = 0x08074b50 |
0/4 | 4 | CRC-32 van ongecomprimeerde data |
4/8 | 4 | gecomprimeerde grootte |
8/12 | 4 | ongecomprimeerde size |
Central directory file headerEdit
De entry in de centrale directory is een uitgebreide vorm van de lokale header:
Offset | Bytes | Description |
---|---|---|
0 | 4 | Central map bestand header signature = 0x02014b50 |
4 | 2 | Versie gemaakt door |
6 | 2 | Versie nodig om uit te pakken (minimum) |
8 | 2 | General purpose bit flag |
10 | 2 | Compressie methode |
12 | 2 | Bestand laatste wijzigingstijd |
14 | 2 | Bestand laatste wijzigingsdatum |
16 | 4 | CRC-32 van ongecomprimeerde gegevens |
20 | 4 | Gecomprimeerde grootte (of 0xffffffff voor ZIP64) |
24 | 4 | Gecomprimeerde grootte (of 0xffffffff voor ZIP64) |
28 | 2 | Bestandsnaamlengte (n) |
30 | 2 | Extra veldlengte (m) |
32 | 2 | lengte van bestandscommentaar (k) |
34 | 2 | schijfnummer waar bestand begint |
36 | 2 | Interne bestandskenmerken |
38 | 4 | Externe bestandskenmerken |
42 | 4 | Relatieve offset van lokale bestandsheader. Dit is het aantal bytes tussen het begin van de eerste schijf waarop het bestand voorkomt, en het begin van de koptekst van het lokale bestand. Dit stelt software die de centrale directory leest in staat om de positie van het bestand binnen het ZIP-bestand te bepalen. |
46 | n | Bestandsnaam |
46+n | m | Extra veld |
46+n+m | k | Bestandstoevoeging |
Einde van centrale directory record (EOCD)Edit
Na alle centrale directory entries komt het einde van centrale directory (EOCD) record, die het einde van het ZIP-bestand markeert:
Offset | Bytes | Description | ||
---|---|---|---|---|
0 | 4 | End of signatuur centrale map = 0x06054b50 | ||
4 | 2 | Nummer van deze schijf | ||
6 | 2 | Disk waar centrale map begint | ||
8 | 2 | Aantal centrale directory records op deze schijf | ||
10 | 2 | Totaal aantal centrale directory records | 2 | Totaal aantal centrale directory records op deze schijf |
12 | 4 | Grootte van centrale directory (bytes) | ||
16 | 4 | Offset van begin van centrale directory, relatief t.o.v. het begin van het archief | ||
20 | 2 | Comment lengte (n) | ||
22 | n | Comment |
Met deze ordening kan een ZIP-bestand in één keer worden gemaakt, maar de centrale directory wordt ook aan het eind van het bestand geplaatst om het gemakkelijk verwijderen van bestanden uit meerdelige (bijv.b.v. “multiple floppy-disk”) archieven, zoals eerder besproken.
CompressiemethodenEdit
De .ZIP File Format Specification documenteert de volgende compressiemethoden: Store (geen compressie), Shrink (LZW), Reduce (niveaus 1-4; LZ77 + probabilistisch), Implode, Deflate, Deflate64, bzip2, LZMA, WavPack, PPMd, en een LZ77-variant geleverd door IBM z/OS CMPSC instructie. De meest gebruikte compressiemethode is DEFLATE, die wordt beschreven in IETF RFC 1951.
Andere methoden die worden genoemd, maar niet in detail zijn gedocumenteerd in de specificatie zijn onder andere: PKWARE DCL Implode (oude IBM TERSE), nieuwe IBM TERSE, IBM LZ77 z Architecture (PFS), en een JPEG-variant. Een “Tokenize” methode was gereserveerd voor een derde partij, maar ondersteuning is nooit toegevoegd.
Het woord Implode wordt door PKWARE te veel gebruikt: de DCL/TERSE Implode is te onderscheiden van de oude PKZIP Implode, een voorganger van Deflate. De DCL Implode is niet gedocumenteerd, gedeeltelijk vanwege het eigendomsrecht van IBM, maar Mark Adler heeft desondanks een decompressor genaamd “blast” beschikbaar gesteld naast zlib.
EncryptionEdit
ZIP ondersteunt een eenvoudig symmetrisch encryptie-systeem op basis van een wachtwoord, algemeen bekend als ZipCrypto. Het is gedocumenteerd in de ZIP specificatie, en bekend is dat het ernstige gebreken vertoont. Het is met name kwetsbaar voor “known-plaintext”-aanvallen, die in sommige gevallen worden verergerd door slechte implementaties van random-nummergeneratoren.
Nieuwe functies, waaronder nieuwe compressie- en encryptiemethoden (b.v. AES), zijn sinds versie 5.2 gedocumenteerd in de ZIP File Format Specification. Een door WinZip ontwikkelde open standaard op basis van AES (“AE-x” in APPNOTE) wordt ook gebruikt door 7-Zip en Xceed, maar sommige verkopers gebruiken andere formaten. PKWARE SecureZIP (SES, merkgebonden) ondersteunt ook RC2-, RC4-, DES-, Triple DES-versleutelingsmethoden, versleuteling en authenticatie op basis van digitale certificaten (X.509), en versleuteling van archiefkoppen. Het is echter gepatenteerd (zie § Sterke encryptie controverse).
File name encryption is geïntroduceerd in .ZIP File Format Specification 6.2, waarmee metadata opgeslagen in Central Directory gedeelte van een archief wordt versleuteld, maar Local Header secties blijven onversleuteld. Een conforme archiver kan de Local Header-gegevens vervalsen wanneer Central Directory Encryption wordt gebruikt. Vanaf versie 6.2 van de specificatie worden de velden Compressiemethode en Gecomprimeerde grootte binnen de Local Header nog niet gemaskeerd.
ZIP64Edit
Het oorspronkelijke .ZIP-formaat had een limiet van 4 GiB (232 bytes) op diverse zaken (ongecomprimeerde grootte van een bestand, gecomprimeerde grootte van een bestand, en totale grootte van het archief), evenals een limiet van 65.535 (216) entries in een ZIP-archief. In versie 4.5 van de specificatie (die niet hetzelfde is als v4.5 van een bepaald gereedschap), introduceerde PKWARE de “ZIP64” formaatuitbreidingen om deze beperkingen te omzeilen, waarbij de limieten werden verhoogd tot 16 EiB (264 bytes). In essentie gebruikt het een “normale” centrale directory entry voor een bestand, gevolgd door een optionele “zip64” directory entry, die de grotere velden heeft.
Het formaat van de Local file header en Central directory entry zijn hetzelfde in ZIP en ZIP64, maar voor de grootte altijd 0xffffffff opgeslagen, en een extra veld bestaat altijd:
Offset | Bytes | Description |
---|---|---|
0 | 2 | Header ID 0x0001 |
2 | 2 | Grootte van het extra veld chunk (16, 24 of 28) |
4 | 8 | Oorspronkelijke ongecomprimeerde bestandsgrootte |
12 | 8 | Grootte van de gecomprimeerde gegevens |
20 | 8 | Offset van lokale header record |
28 | 4 | Nummer van de schijf waarop dit bestand begint |
Aan de andere kant, is het formaat van EOCD voor ZIP64 iets anders dan de normale ZIP versie (zie appnote sectie 4.3.14).
Offset | Bytes | Description | |||
---|---|---|---|---|---|
0 | 4 | Eind van centrale directory signatuur = 0x06064b50 | |||
4 | 8 | Grootte van de EOCD64 – | 4 | 8 | 8 |
12 | 2 | Versie gemaakt door | |||
14 | 2 | Versie nodig om te extraheren (minimum) | |||
16 | 4 | Nummer van deze schijf | |||
20 | 4 | Disk waar centrale directory begint | |||
24 | 8 | Aantal records centrale map op deze schijf | |||
32 | 8 | Totaal aantal records centrale map | |||
40 | 8 | Grootte van centrale directory (bytes) | |||
48 | 8 | Offset van begin van centrale directory, relatief ten opzichte van het begin van het archief | |||
56 | n | Commentaar (tot de grootte van EOCD64) |
Het is ook niet noodzakelijk het laatste record in het bestand, er kan een optionele End of Central Directory Locator volgen (een extra 20 bytes aan het eind).
De File Explorer in Windows XP ondersteunt geen ZIP64, maar de Explorer in Windows Vista en later wel. Ook sommige extensie bibliotheken ondersteunen ZIP64, zoals DotNetZip, QuaZIP en IO::Compress::Zip in Perl. Python’s ingebouwde zipfile ondersteunt het sinds 2.5 en gaat er standaard naar toe sinds 3.4. OpenJDK’s ingebouwde java.util.zip ondersteunt ZIP64 vanaf versie Java 7. Android Java API ondersteunt ZIP64 sinds Android 6.0. Mac OS Sierra’s Archive Utility ondersteunt ZIP64 niet, en kan corrupte archieven maken wanneer ZIP64 vereist zou zijn. Het ditto commando dat met Mac OS wordt meegeleverd kan echter ZIP64 bestanden uitpakken. Recentere versies van Mac OS worden geleverd met info-zip’s zip en unzip command line tools die Zip64 wel ondersteunen: om dit te verifiëren voert u zip -v uit en zoekt u naar “ZIP64_SUPPORT”.
Combinatie met andere bestandsformatenEdit
Het .ZIP bestandsformaat staat toe dat een commentaar met maximaal 65.535 (216-1) bytes aan gegevens aan het eind van het bestand komt na de centrale directory. Omdat de centrale directory de offset van elk bestand in het archief ten opzichte van de start specificeert, is het ook mogelijk dat het eerste bestand op een andere offset dan nul begint, hoewel sommige tools, bijvoorbeeld gzip, geen archiefbestanden zullen verwerken die niet beginnen met een bestand op offset nul.
Dit maakt het mogelijk dat willekeurige gegevens in het bestand zowel voor als na de ZIP-archiefgegevens voorkomen, en dat het archief nog steeds door een ZIP-toepassing kan worden gelezen. Een neveneffect hiervan is dat het mogelijk is om een bestand te maken dat zowel een werkend ZIP archief is als een ander formaat, op voorwaarde dat het andere formaat arbitraire gegevens aan het eind, begin of midden tolereert. Self-extracting archives (SFX), in de door WinZip ondersteunde vorm, maken hier gebruik van, in die zin dat het uitvoerbare (.exe) bestanden zijn die voldoen aan de PKZIP AppNote.txt specificatie, en kunnen worden gelezen door zip-tools of -bibliotheken die aan de eisen voldoen.
Deze eigenschap van het .ZIP formaat, en van het JAR formaat dat een variant is van ZIP, kan worden misbruikt om malafide inhoud (zoals schadelijke Java classes) te verbergen in een schijnbaar onschuldig bestand, zoals een GIF afbeelding die naar het web wordt ge-upload. Deze zogenaamde GIFAR-exploit is gedemonstreerd als een effectieve aanval tegen webtoepassingen zoals Facebook.
LimitsEdit
De minimale grootte van een .ZIP-bestand is 22 bytes. Zo’n leeg zip-bestand bevat alleen een End of Central Directory Record (EOCD):
De maximale grootte voor zowel het archiefbestand als de afzonderlijke bestanden daarin is 4,294,967,295 bytes (232-1 bytes, of 4 GiB minus 1 byte) voor standaard ZIP. Voor ZIP64 is de maximale grootte 18.446.744.073.709.551.615 bytes (264-1 bytes, of 16 EiB minus 1 byte).
Eigendoms-extensiesEdit
Extra veldEdit
.Het ZIP-bestandsformaat bevat een voorziening voor extra velden in de bestandskoppen, die kan worden gebruikt om extra gegevens op te slaan die niet zijn gedefinieerd in de bestaande ZIP-specificaties, en die compatibele archiveringsprogramma’s die de velden niet herkennen, in staat stelt ze veilig over te slaan. Header IDs 0-31 zijn gereserveerd voor gebruik door PKWARE. De overige ID’s kunnen worden gebruikt door derde-partij leveranciers voor eigen gebruik.
Sterke encryptie controverseEdit
Toen WinZip 9.0 publieke beta werd uitgebracht in 2003, introduceerde WinZip zijn eigen AES-256 encryptie, gebruikmakend van een ander bestandsformaat, samen met de documentatie voor de nieuwe specificatie. De encryptiestandaarden zelf waren niet propriëtair, maar PKWARE had APPNOTE.TXT niet bijgewerkt om de Strong Encryption Specification (SES) op te nemen sinds 2001, die door PKZIP versies 5.0 en 6.0 werd gebruikt. WinZip technisch adviseur Kevin Kearney en StuffIt product manager Mathew Covington beschuldigden PKWARE van het achterhouden van SES, maar PKZIP chief technology officer Jim Peterson beweerde dat op certificaten gebaseerde encryptie nog steeds onvolledig was.
In een andere controversiële zet, vroeg PKWare op 16 juli 2003 patent aan op een methode voor het combineren van ZIP en sterke encryptie om een veilig bestand te creëren.
Uiteindelijk kwamen PKWARE en WinZip overeen om elkaars producten te ondersteunen. Op 21 januari 2004 kondigde PKWARE de ondersteuning aan van het op WinZip gebaseerde AES compressieformaat. In een latere versie van WinZip beta, was het mogelijk om op SES gebaseerde ZIP bestanden te ondersteunen. PKWARE gaf uiteindelijk versie 5.2 van de .ZIP File Format Specification vrij aan het publiek, waarin SES werd gedocumenteerd. Het Free Software project 7-Zip ondersteunt ook AES, maar niet SES in ZIP bestanden (net als zijn POSIX port p7zip).
Bij gebruik van AES encryptie onder WinZip, is de compressie methode altijd ingesteld op 99, met de werkelijke compressie methode opgeslagen in een AES extra data veld. De Strong Encryption Specification slaat de compressiemethode daarentegen op in het basissegment van de bestandsheader van de Local Header en Central Directory, tenzij Central Directory Encryption wordt gebruikt om metagegevens te maskeren/versleutelen.