Gzip
Tempel gzip, zlib, atau deflate mentah dalam Base64 untuk membaca isinya (bitanya yang menentukan), atau kompres teks ke salah satunya, di peramban Anda.
[
{
"name": "Siti",
"city": "Jakarta"
},
{
"name": "Budi",
"city": "Surabaya"
},
{
"name": "Putri",
"city": "Bandung"
},
{
"name": "Agus",
"city": "Medan"
},
{
"name": "Dewi",
"city": "Yogyakarta"
},
{
"name": "Rizky",
"city": "Makassar"
},
{
"name": "Ayu",
"city": "Denpasar"
},
{
"name": "Fajar",
"city": "Semarang"
}
]Dibaca sebagai gzip.
- Bita yang tidak dikompres
- 417
- Bita yang dikompres
- 161
- Perubahan
- -61,4%
- Karakter Base64
- 216
Satu kompresi dalam tiga pembungkus, dan kata deflate
gzip, zlib, dan deflate mentah adalah satu kompresi, DEFLATE, yang dibungkus dengan tiga cara. RFC 1951 mendefinisikan DEFLATE itu sendiri: bitanya dipotong menjadi blok-blok, dan masing-masing ditulis sebagai kode yang mewakili bita tunggal atau deretan bita yang disalin dari bagian sebelumnya. Pembungkus gzip, RFC 1952, menaruh tajuk sepanjang sedikitnya sepuluh bita di depan dan delapan bita di belakang, yaitu CRC-32 dari bita aslinya beserta panjangnya; pembungkus zlib, RFC 1950, menaruh dua bita di depan dan Adler-32 di belakang; deflate mentah adalah kompresi itu tanpa pembungkus sama sekali. Data yang dikompres di dalamnya bisa sama di ketiganya, jadi seluruh perbedaannya terletak pada pembungkus.
Kata deflate adalah titik tempat nama-nama menjadi kusut. Bagi HTTP, Content-Encoding: deflate berarti pembungkus zlib, dan RFC 9110 mencatat bahwa sebagian server tetap mengirim deflate mentah dengan nama itu. Kompresor peramban itu sendiri mengikuti HTTP: pembungkus zlib disebutnya dengan nama deflate, dan deflate mentah dengan nama deflate-raw. DeflateStream milik .NET dan gzdeflate milik PHP menulis deflate mentah, sedangkan gzcompress milik PHP dan zlib.compress milik Python menulis pembungkus zlib. Jadi bita yang berlabel deflate bisa salah satu dari keduanya, dan hanya bitanya yang bisa mengatakan yang mana.
Itulah sebabnya halaman ini membaca pembungkus dari bitanya saat mendekompres, dan menyebut mana yang dibacanya di bawah hasilnya: “Dibaca sebagai gzip”, “Dibaca sebagai zlib”, atau “Dibaca sebagai deflate mentah”. Bitanya yang memastikan: gzip selalu diawali 1f 8b, dua bita pertama zlib, bila dibaca bersama sebagai satu bilangan, merupakan kelipatan 31, dan tidak ada penyandi yang mengawali deflate mentah dengan salah satu dari keduanya. Berkas yang namanya berakhiran .gz tetapi berisi zlib dibaca sebagai zlib, dengan pemberitahuan bahwa nama dan bitanya tidak sejalan, dan bita yang bukan salah satu dari ketiganya ditolak, karena tidak ada yang bisa didekompres. Saat mengompres, Anda yang memilih pembungkusnya, dan pilihannya gzip sampai Anda memilih yang lain.
Dari mana muatan berasal, dan apa itu H4sI dan eJ
Bita yang dikompres sampai ke pengembang dalam beberapa bentuk: sebagai badan respons HTTP dengan Content-Encoding yang menyebut gzip atau deflate, sebagai berkas, atau sebagai teks, yang ditulis dalam Base64 atau heksadesimal. Setiap aliran gzip diawali tiga bita yang sama, 1f 8b 08 — dua bita tanda tangannya dan nomor metode kompresinya, yaitu DEFLATE — dan tiga bita tepat menjadi empat karakter Base64, jadi gzip yang ditulis dalam Base64 selalu diawali H4sI. Itulah yang diserahkan langganan CloudWatch Logs kepada fungsi Lambda atau aliran Kinesis dalam data setiap catatan, dan begitulah Helm menyimpan rilis: JSON-nya dikompres dengan gzip, lalu ditulis dalam Base64. Bila Helm menyimpan rilis dalam Secret Kubernetes, membacanya langsung dari Secret itu menghasilkan Base64 di dalam Base64, karena Secret menyimpan datanya dalam Base64 tersendiri; alat Base64 mendekode lapisan luar itu menjadi H4sI… yang dibaca halaman ini.
Dua bita tajuk zlib menyebut metodenya, jendelanya, dan tingkat kompresi yang dipakai saat menulisnya, jadi dengan jendela bawaan zlib, Base64-nya diawali dengan salah satu dari empat cara: eJ pada tingkat bawaan, yang ditulis zlib.compress milik Python kecuali diminta lain, eA atau eF pada tingkat di bawahnya, dan eN pada tingkat di atasnya. Tidak ada tanda tangan sama sekali pada deflate mentah, dan Base64-nya diawali dengan apa pun yang kebetulan mengawali blok pertamanya.
“Dikompres sebagai” menentukan cara halaman ini membaca dan menulis bita itu sebagai teks: “Base64”, seperti saat halaman dibuka, atau “Heksadesimal”. Pilihan itu berlaku di kedua arah, dan halaman ini tidak pernah mengubahnya untuk Anda, karena setiap digit heksadesimal juga merupakan karakter Base64, sehingga 1f8b0800 adalah teks di keduanya dan bita yang berbeda di masing-masing. Base64 dibaca dalam alfabet standar atau alfabet aman-URL, dengan atau tanpa padding, melewati spasi dan pemutus baris, dan ditulis dengan padding, atau aman-URL tanpa padding saat sakelar “Aman-URL” menyala. Heksadesimal ditulis dalam pasangan berspasi dan dibaca berspasi atau bersambung, dengan 0x di depan, atau sebagai dump heksadesimal — dan 0x adalah cara T-SQL menulis nilai biner, seperti gzip yang dikembalikan COMPRESS() milik SQL Server. Ketika heksadesimal yang dibaca sebagai Base64 gagal, atau Base64 yang dibaca sebagai heksadesimal ditolak di karakter yang tidak dimiliki heksadesimal, dan dalam kedua kasus itu seluruh teks terbaca dengan cara yang satunya, pemberitahuan mengatakannya, dengan tombol untuk beralih di sampingnya; tidak ada yang beralih sampai Anda menekannya.
Membaca aliran: anggota, bita sesudahnya, dan akhir yang terlalu dini
RFC 1952 menjadikan berkas gzip serangkaian anggota, yaitu aliran gzip utuh yang tersusun satu di belakang yang lain, masing-masing dengan tajuk dan ekornya sendiri. cat a.gz b.gz membuat berkas seperti itu, begitu pula menambahkan isi ke berkas seperti itu dengan gzip -c file >> archive.gz, contoh dari manual GNU gzip itu sendiri; gunzip membaca setiap anggota dan menggabungkan isinya. Halaman ini membacanya dengan cara yang sama: setiap anggota dibaca dan diperiksa, isinya ditampilkan tergabung, dan pemberitahuan menyebut berapa anggota yang dibaca. Tidak semua program pembaca melakukan hal ini. Standar yang diikuti peramban sendiri saat mendekompres hanya mengizinkan satu anggota dalam aliran gzip dan menyebut anggota kedua sebagai galat, dan zlib.decompress milik Python berhenti setelah anggota pertama tanpa sepatah kata.
Bita yang ada sesudah akhir aliran dan tidak mengawali anggota mana pun dilewati alih-alih ditolak, karena semua yang ada sebelumnya sudah utuh dan diperiksa, dan pemberitahuan menyebut berapa banyak bita itu, offset tempatnya dimulai, dan apakah semuanya nol. Nol di sana adalah padding — manual GNU gzip menjumpainya pada pita magnetik, ditulis sampai akhir blok — dan gunzip melewatinya tanpa sepatah kata; bita lain dilewatinya dengan peringatan bahwa sampah di bagian belakang diabaikan, sedangkan gzip.decompress milik Python menolak berkas itu. Hal yang sama berlaku sesudah Adler-32 aliran zlib, dan sesudah blok terakhir aliran mentah, meski deflate mentah tidak membawa checksum untuk diperiksa.
Aliran yang berhenti sebelum akhirnya, misalnya tempelan yang terpotong atau unduhan yang terhenti di tengah jalan, ditampilkan sejauh yang ada, dengan pemberitahuan bahwa checksum-nya tidak diperiksa. Aliran yang rusak ditolak, dan tidak ada bagiannya yang ditampilkan. Itu lebih ketat daripada gunzip, yang menuliskan apa yang sudah didekompresnya sebelum sampai ke checksum yang mendapati hasilnya salah; tetapi bit yang berubah bisa terdekode diam-diam untuk beberapa lama sebelum ada yang memperlihatkannya, jadi bita yang keluar sebelum kerusakan terlihat bisa saja sudah salah. Posisi kerusakan juga tidak diberikan, karena tempat pendekode menyadari kerusakan bukanlah tempat kerusakan itu berada. Dan aliran zlib yang meminta kamus prasetel ditolak dengan kalimatnya sendiri: aliran itu mengidentifikasi bita yang lebih dulu diberikan kepada kompresornya, tetapi tidak membawanya, jadi tidak ada yang bisa dipakai untuk membacanya.
Yang keluar ditulis sesuai “Bita sebagai”: sebagai “Teks” dalam UTF-8, atau sebagai “Heksadesimal”. Sering kali isinya JSON, yang dipercantik dan divalidasi oleh Pemformat JSON, yang menunjukkan baris dan kolom galatnya. Gambar atau arsip yang dikompres dengan gzip bukan teks, jadi dengan “Bita sebagai” pada “Teks”, setiap deretan bitanya yang bukan UTF-8 tampil sebagai U+FFFD, dengan pemberitahuan yang menghitung deretan itu di samping tombol yang menampilkan bitanya sebagai heksadesimal; “Unduh” menyimpan bita itu sendiri apa pun pilihannya. Baris di bawah hasil menampilkan apa yang disimpan tajuk anggota pertama — nama, waktu dalam UTC, dan komentar — dan nama tersimpan itu tidak pernah dipakai sebagai nama berkas yang disimpan “Unduh”. Keluaran yang melewati batas terbanyak yang didekompres halaman ini sekaligus berhenti di situ, dengan pemberitahuan yang menyebut ukuran itu, dan bila ekor gzip menyatakan panjang yang melebihi batas itu, halaman ini mengatakannya selagi pekerjaannya berjalan.
Mengapa masukan kecil membesar, dan apa yang ditambahkan Base64
Kompresi menghemat ukuran dengan menemukan pengulangan, dan teks pendek hanya punya sedikit pengulangan, sementara setiap pembungkus menambahkan bita miliknya sendiri: tajuk dan ekor gzip berjumlah 18 bita bila tajuknya tidak menyimpan apa pun lagi, pada zlib 6, dan deflate mentah tidak punya sama sekali, meski DEFLATE menghabiskan beberapa bit untuk menandai blok-bloknya. Jadi Hello, world!, 13 bita, menjadi 33 bita sebagai gzip, 21 sebagai zlib, dan 15 sebagai deflate mentah. Baris ukuran di bawah hasil menghitung bita di kedua sisi dan perubahan di antara keduanya, +153,8% untuk gzip itu, dan pemberitahuan menjelaskan sebabnya bila hasil membesar. Teks dengan banyak pengulangan, seperti JSON atau log, menutup biaya itu berkali-kali lipat: contoh yang dimuat halaman ini saat dibuka, JSON kecil, keluar dengan ukuran kurang dari separuhnya.
Bila ditulis sebagai teks, bitanya memakan lebih banyak lagi. Base64 memakai empat karakter untuk setiap tiga bita, sepertiga lebih banyak, seperti yang dijelaskan panduan alat Base64, jadi 33 bita gzip tadi menjadi 44 karakter; heksadesimal memakai dua digit per bita, dan halaman ini menulisnya dalam pasangan berspasi, 98 karakter untuk 33 bita yang sama. Baris ukuran juga menghitung karakter itu, dan Konverter ukuran bita mengubah hitungan mana pun darinya menjadi KB atau KiB.
Mengompres: tanpa tingkat kompresi, bukan bita gzip -c, dan tanpa Brotli
Mengompres adalah pekerjaan peramban itu sendiri, melalui CompressionStream yang didefinisikan standar Compression, dan standar itu tidak menawarkan tingkat kompresi, jadi halaman ini juga tidak: yang Anda dapatkan adalah tingkat bawaan peramban. gzip -9 bisa keluar sedikit lebih kecil, dan jarang dengan selisih yang besar.
Bitanya juga bukan bita yang ditulis gzip -c, meski keduanya terdekompres menjadi teks yang sama. Yang pertama berbeda adalah tajuknya. GNU gzip menyimpan nama dan waktu berkas kecuali diberi -n, dan dari pipa menyimpan waktu nol; ia mencatat tanda tingkat yang dipakai, -9 atau -1, di salah satu bita tajuknya; dan di bita kesepuluh, yang oleh RFC 1952 diberikan kepada sistem operasi, ia menulis 03 di Linux, nomor untuk Unix. Peramban hanya menerima bitanya, jadi baik nama maupun waktu berkas Anda tidak bisa ikut keluar bersama hasilnya: Chromium tidak menyimpan nama dan menyimpan waktu nol, seperti yang dipilih gzip -n, dan di bita kesepuluh ia menulis 03 di Linux, sedangkan Chrome di Windows menulis 0a. Lalu data yang dikompres pun berbeda, karena kompresor GNU gzip bukan kompresor peramban: pada teks yang panjang, keduanya memilih bita yang berbeda pada tingkat yang sama. Karena itu ketidakcocokan dengan gzip -c tidak berarti apa-apa dengan sendirinya; yang penting adalah keduanya terdekompres menjadi bita yang sama.
Brotli tidak ada di sini, untuk saat ini. Standar Compression menyebutnya, tetapi belum semua peramban menulisnya, dan pilihan yang hanya bisa ditawarkan halaman ini di peramban yang mampu membuatnya akan menjadikan halaman ini halaman yang berbeda di peramban yang berbeda. zstd sama sekali tidak ada dalam standar itu. Yang dibaca dan ditulis halaman ini adalah DEFLATE dalam tiga pembungkusnya, dan tidak ada yang lain.
Berkas masuk, berkas keluar, dan tidak ada yang diunggah
Berkas bisa menggantikan kotak teks di kedua arah: pilih satu, atau jatuhkan ke kotak. Bitanya dibaca apa adanya, tanpa melalui “Dikompres sebagai” atau “Bita sebagai”, dan berkas tidak punya batas di sini, sedangkan kotak teks punya, meski berkas yang sangat besar memunculkan peringatan bahwa peramban mungkin tidak mampu menahannya. Saat mendekompres, “Unduh” menamai hasilnya seperti yang dilakukan gunzip: nama berkas tanpa .gz, dengan .tgz menjadi .tar, dan juga tanpa .zz atau .deflate, akhiran yang ditulis halaman ini untuk dua pembungkus lainnya; nama lain apa pun, dan apa pun yang ditempel, keluar sebagai bytes.bin. Saat mengompres, “Unduh” menambahkan .gz, .zz, atau .deflate ke nama berkas — .zz adalah cara pigz menamai zlib — atau ke kata text untuk yang Anda ketik.
“Gunakan sebagai masukan” memindahkan hasil ke kotak dan membalik arahnya, sehingga perjalanan bolak-balik cukup dengan satu klik, dan hasil yang berasal dari berkas, atau terlalu besar untuk kotak, dipindahkan sebagai berkas. Ke arah mana pun, berkas dibaca di tab ini dan pekerjaannya berjalan di Web Worker yang dijalankan halaman ini di perangkat Anda sendiri: baik muatan maupun berkas tidak diunggah untuk itu.
Hal yang sama dengan gunzip dan Python
Di baris perintah, gunzip dan zcat membaca gzip seperti halaman ini, termasuk setiap anggotanya, setelah base64 -d mengembalikan muatan menjadi bita, meski keduanya tidak membaca zlib atau deflate mentah, yang ditolak keduanya karena bukan gzip; gzip -k mengompres berkas dan menyimpan berkas aslinya di sampingnya. Di Python, gzip.decompress membaca pembungkus gzip beserta setiap anggota di dalamnya, dan zlib.decompress membaca pembungkus mana pun dari ketiganya, sesuai nilai wbits yang diberikan kepadanya:
# A payload: decode it, then decompress it
printf 'H4sIAAAAAAAAA/NIzcnJ11Eozy/KSVEEAObG5usNAAAA' | base64 -d | gunzip # Hello, world!
# A file: compress it, keeping the original, then print it back
printf 'Hello, world!' > hello.txt
gzip -k hello.txt
zcat hello.txt.gz # Hello, world!
# Two members, the second appended to the first, read back as one
printf 'Hello, ' | gzip > two.gz
printf 'world!' | gzip >> two.gz
zcat two.gz # Hello, world!
# The same in a script: every member, then one wrapper at a time
import base64, gzip, zlib
two = open('two.gz', 'rb').read()
zl = base64.b64decode('eJzzSM3JyddRKM8vyklRBAAgXgSK')
raw = base64.b64decode('80jNycnXUSjPL8pJUQQA')
gzip.decompress(two) # b'Hello, world!'
zlib.decompress(two, wbits=31) # b'Hello, '
zlib.decompress(zl, wbits=15) # b'Hello, world!'
zlib.decompress(raw, wbits=-15) # b'Hello, world!'
zlib.decompress(zl, wbits=47) # b'Hello, world!'Dengan wbits, 31 meminta pembungkus gzip, sedangkan 15, nilai bawaannya, meminta pembungkus zlib, dan -15 meminta deflate mentah — angka 15 di dalam masing-masing nilai itu adalah jendela terbesar — sementara 47 menerima pembungkus gzip atau zlib, mana pun yang mengawali bitanya. Namun zlib.decompress hanya membaca satu anggota dan membuang sisanya tanpa sepatah kata, itulah sebabnya dari dua anggota di atas ia hanya mengembalikan b'Hello, '; gzip.decompress membaca semuanya. Python juga lebih ketat daripada halaman ini dalam dua hal: gzip.decompress menolak bita sesudah akhir yang bukan nol, dan kedua fungsi itu menolak aliran yang berakhir terlalu dini, sedangkan halaman ini menampilkan apa yang keluar.
Pertanyaan yang sering diajukan
- Mengapa hasil kompresi saya lebih besar daripada yang saya ketik?
- Karena setiap pembungkus menambahkan bita miliknya sendiri dan teks pendek hanya punya sedikit yang bisa dibuang oleh kompresi: gzip menambahkan 18 bita, zlib 6, dan DEFLATE masih menandai blok-bloknya pula, jadi beberapa kata justru membesar, sementara JSON yang panjang menyusut, dan halaman ini mengatakannya dalam pemberitahuan. Di antara ketiganya, deflate mentah yang paling kecil. Bila ditulis dalam Base64, hasil apa pun menjadi sepertiga lebih panjang lagi.
- Mengapa keluarannya tidak cocok dengan gzip -c?
- Tidak ada yang menjanjikan keduanya akan cocok. Tajuk gzip bisa memuat nama, waktu, tanda tingkat kompresi, dan bita untuk sistem operasi, yang diisi GNU gzip dan peramban dengan cara berbeda, dan keduanya adalah kompresor yang berbeda, jadi pada teks yang lebih panjang bahkan data di antara tajuk dan ekor pun bisa berbeda. Dua aliran gzip dari satu teks sama-sama benar bila masing-masing terdekompres menjadi teks itu, jadi bandingkan hasil dekompresinya: “Gunakan sebagai masukan” langsung mengirim hasil halaman ini ke arah sebaliknya.
- Apa arti H4sI di awal muatan?
- Artinya muatan itu adalah gzip yang ditulis dalam Base64: setiap aliran gzip diawali bita 1f 8b 08, dan ketiga bita itu adalah H4sI dalam Base64. Tempel di sini apa adanya. Muatan yang diawali eJ kemungkinan besar adalah zlib pada tingkat bawaannya, dan muatan yang tidak diawali keduanya mungkin deflate mentah, atau sama sekali tidak dikompres, yang akan diberitahukan halaman ini kepada Anda.
- Apakah gzip merupakan enkripsi?
- Tidak. Kompresi tidak memakai kunci, jadi siapa pun yang memegang bitanya bisa mendekompresnya, di sini atau dengan gunzip, dan setiap bitanya kembali. Kata sandi di dalam muatan yang dikompres dengan gzip sama terbukanya dengan kata sandi yang ditulis utuh.
- Apakah muatan atau berkas saya diunggah ke suatu tempat?
- Tidak. Muatan yang Anda tempel dan berkas yang Anda pilih atau jatuhkan sama-sama dibaca di dalam tab ini, tempat Web Worker yang dijalankan halaman ini mengerjakan kompresi dan dekompresinya, dan “Unduh” membuat berkasnya dari hasil itu di sana juga. Tidak satu pun dari keduanya dikirim ke situs ini atau ke pihak lain mana pun.
Alat terkait
- Pemformat JSON
Validasi dan percantik JSON, dengan lokasi galat yang jelas.
- Konverter ukuran bita
Konversi antara KB, MB, GB dan KiB, MiB, GiB.
- Base64
Kodekan dan dekode Base64 — dukungan UTF-8 penuh.
- Base32
Kodekan dan dekode Base32 dan base32hex — teks dalam UTF-8 atau bita dalam heksadesimal.