Tujuan
Buat program atau pasangan program yang secara kolektif mengganggu dan memperbaiki file dengan maksud mencegah LZMA2 bekerja secara efektif. Mengganggu dan memperbaiki rutinitas harus bersifat timbal balik, sehingga Anda dapat memulihkan file asli dengan tepat.
Target
- Karya-karya Shakespeare yang terkumpul dalam dataran UTF-8 (5.589.891 byte)
- Wikimedia Commons 2013 Picture of the Year pada resolusi penuh (1,659,847 bytes)
Metode Kompresi
- Ubuntu / terkait:
xz -kz5 <infile>
- Windows:
7z.exe a -txz -mx5 <outfile> <infile>
- Lainnya: Gunakan kompresor LZMA2 dengan tingkat kompresi 5 yang mengkompres pekerjaan Shakespeare ke 1570550 byte ± 100 byte.
Mencetak; jumlah (semuanya dalam byte, ls -l
atau dir
itu):
- Ukuran program (apa pun yang diperlukan secara kolektif untuk memulihkan "kerusakan" / memperbaiki file)
- Perbedaan ukuran (absolut) antara:
- Karya Shakespeare yang dikumpulkan dan salinan modifikasi Anda (tidak terkompresi).
- Foto mentah dan salinan Anda yang dimodifikasi (tidak dikompresi).
- Perbedaan ukuran atau 0, mana yang lebih besar antara:
- Karya Shakespeare terkumpul mentah dikurangi salinan LZMA2 terkompresi yang dimodifikasi.
- Foto mentah dikurangi salinan terkompresi Anda, LZMA2.
Contoh
Skor buruk, malas bermain golf, tapi Python 2.x yang patuh contoh:
import sys
x = 7919 if sys.argv[1] == 'b' else -7919
i = bytearray(open(sys.argv[2], 'rb').read())
for n in range(len(i)):
i[n] = (i[n] + x*n) % 256
o = open(sys.argv[2]+'~', 'wb').write(i)
Berlari ...
$ python break.py b pg100.txt
$ python break.py f pg100.txt~
$ diff -s pg100.txt pg100.txt~~
Files pg100.txt and pg100.txt~~ are identical
$ python break.py b Glühwendel_brennt_durch.jpg
$ python break.py f Glühwendel_brennt_durch.jpg~
$ diff -s Glühwendel_brennt_durch.jpg Glühwendel_brennt_durch.jpg~~
Files Glühwendel_brennt_durch.jpg and Glühwendel_brennt_durch.jpg~~ are identical
$ xz -kz5 pg100.txt~
$ xz -kz5 Glühwendel_brennt_durch.jpg~
$ ls -ln
-rw-rw-r-- 1 2092 2092 194 May 23 17:37 break.py
-rw-rw-r-- 1 2092 2092 1659874 May 23 16:20 Glühwendel_brennt_durch.jpg
-rw-rw-r-- 1 2092 2092 1659874 May 23 17:39 Glühwendel_brennt_durch.jpg~
-rw-rw-r-- 1 2092 2092 1659874 May 23 17:39 Glühwendel_brennt_durch.jpg~~
-rw-rw-r-- 1 2092 2092 1646556 May 23 17:39 Glühwendel_brennt_durch.jpg~.xz
-rw-rw-r-- 1 2092 2092 5589891 May 23 17:24 pg100.txt
-rw-rw-r-- 1 2092 2092 5589891 May 23 17:39 pg100.txt~
-rw-rw-r-- 1 2092 2092 5589891 May 23 17:39 pg100.txt~~
-rw-rw-r-- 1 2092 2092 3014136 May 23 17:39 pg100.txt~.xz
Skor
- = 194 + abs (5589891 - 5589891) + maks (5589891 - 3014136, 0) + abs (1659874 - 1659874) + maks (1659874 - 1646556, 0)
- = 194 + 0 + 2575755 + 0 + 13318
- 2.589.267 byte. Buruk, tetapi tidak melakukan apa pun pada file menghasilkan skor 4.635.153 byte.
Klarifikasi
Ini golf, jadi Anda mencoba meminimalkan skor Anda. Saya tidak yakin apakah komentarnya menunjukkan lubang yang sah dalam penilaian saya atau apakah itu karena saya membuatnya terlalu rumit. Bagaimanapun, Anda menginginkan yang TERKECIL :
- Kode sumber
- perbedaan antara file termodifikasi yang tidak terkompresi dan file asli (mis. jika Anda memodifikasinya dengan menambahkan satu triliun pada akhirnya, skor Anda hanya naik satu triliun byte)
- perbedaan antara file termodifikasi yang dikompresi dan file asli (mis. semakin file tidak dapat dikompres, semakin tinggi skor Anda). File yang sangat tidak bisa dimampatkan yang tumbuh sedikit atau tidak sama sekali akan mendapat skor 0.
code-challenge
compression
Nick T
sumber
sumber
Jawaban:
Python, skor = 120
Membuat pad sekali pakai menggunakan md5 dalam mode penghitung . mengoreksi file dengan itu. Ini memiliki keuntungan bahwa file asli dan yang rusak memiliki ukuran yang sama, dan bahwa pengganggu dan pemecah masalah adalah program yang sama.
File terganggu terkompresi lebih besar dari aslinya.
sumber
C, 51 = 51 + 0 + 0 + 0 + 0
Di bawah trik golf , program ini loop untuk setiap byte dalam input standar, dan melakukan eksklusif-atau dengan pad tak terbatas dari rand (). Saya menguji ini dengan rand () di libc dari OpenBSD 5.5.
Pemakaian:
Untuk menguji program saya, saya menulis script script test.sh (57 baris) untuk mengkompilasi program saya dan menghitung skor saya.
Catatan tentang rand () dan pergeseran kanan
Algoritma kompresi apa pun tidak dapat mengompresi data acak. Saya dapat menyamarkan pg100.txt dan filament.jpg sebagai data acak jika saya mengacaknya dengan stream cipher .
Ide pertama saya adalah membuat-atau plaintext dengan pad untuk membuat ciphertext , kemudian menyimpan ciphertext dan pad di file yang diacak. Ini akan meningkatkan ukuran file, dan meningkatkan skor saya. Pilihan yang jelas adalah menggunakan pad yang sama untuk setiap file, dan hanya menyimpan ciphertext dalam file yang diacak. Jika saya hanya memanggil rand (), ia menggunakan seed default 1 dan membuat pad yang sama setiap waktu.
OpenBSD 5.5 mendefinisikan rand () di stdlib.h dan rand.c :
Ini adalah generator kongruensial linier . Kelemahan besar adalah bahwa bit rendah memiliki periode pendek. Bit pertama memiliki periode 2: jika Anda melempar koin
rand()&1
, itu akan menjadi kepala, ekor, kepala, ekor, dan sebagainya. Bit ke-n memiliki periode 2 n . Ada 31 bit, sehingga seluruh urutan memiliki periode 2 31 .LZMA2 dapat menemukan pola dalam waktu singkat dan mengompresnya. Kode terpendek
~c^rand()
mengambil 8 bit yang rendah dan tidak mencegah kompresi. Pergeseran yang tepat dalam~c^rand()>>9
membantu, tetapi tidak cukup. Saya menggunakan~c^rand()>>23
.~c
SCORE: 4227957 = 40 + 0 + 0 + 4019391 + 208526~c^rand()
SCORE: 2474616 = 47 + 0 + 0 + 2463735 + 10834~c^rand()>>9
SCORE: 350717 = 50 + 0 + 0 + 350667 + 0~c^rand()>>23
SCORE: 51 = 51 + 0 + 0 + 0 + 0sumber
BrainFuck : 129 (129 + 0 + 0 + 0 + 0) *
random.bf (umpan baris ditambahkan untuk dibaca)
Untuk membuat
unrandom.bf
Anda perlu mengubah + terakhir di baris kedua.Sebagian besar kode didasarkan pada Rule30 generator nomor acak berbasis Daniel B Cristofani yang disesuaikan untuk menambahkan nomor ke setiap input dan untuk mengakhiri ketika tidak ada lagi input.
* Saya sudah menguji byte yang telah diproses sejauh ini 212992 (diproses setelah 12 jam) dan kedua file berubah menjadi file terkompresi 213064. Saya kira itu mungkin dilakukan pada akhir minggu untuk mengetahui dengan pasti tetapi saya tidak ingin menunggu dengan posting. Saya akan memperbarui skor jika itu salah, tetapi pertahankan solusinya karena Rule30 mendukung!
Trivia: Aturan 30 ditemukan oleh Stephen Wolfram pada tahun 1983 dan menurut Wikipedia digunakan untuk menghasilkan bilangan bulat acak di Mathematica.
Kompilasi dan berjalan:
Ini menggunakan waktu dan ruang eksponensial (lebih dari 32 lebih banyak sel per char diproses) sehingga memerlukan runtime BrainFuck yang memiliki setidaknya 178.876.517 sel untuk menyandikan file Shakespear, tidak memperlakukan non ascii sebagai unicode, memiliki sel lebih dari 8 bit dan menggunakan -1 sebagai eof (berbeda antara 255 dan -1). Saya biasanya menggunakan penerjemah orang lain, tetapi kali ini saya harus menjadi penyambung dan mempromosikan sendiri:
jitfb mengkompilasi BrainFuck untuk mengoptimalkan C dan menyalahgunakan perl Inline :: C untuk menjalankannya. Ini bundel dengan kompiler Extended BrainFuck saya . Dengan ukuran dan lebar sel dalam argumen itu akan mengalokasikan sekitar 400MB.
sumber
CJam, 22 byte
Ini menggunakan generator Fibonacci lagged dengan relasi pengulangan s n = (s n-5 + s n-16 )% 255 (yang saya pilih secara tidak sengaja, tetapi tetap berfungsi) dan seed trivial untuk menghasilkan aliran byte pseudo-acak byte , yang kemudian XOR dengan input.
Saya telah menguji kode saya dengan CJam 0.6 , yang diterbitkan pada 1 Mei 2014.
Bagaimana itu bekerja
Skor
sumber
PHP, 117 + 0 + 0 + 0 + 0 = 117
Karena apakah Anda benar-benar akan mempercayakan tugas mengatur data Anda di luar pengenalan ke bahasa lain?
Sementara semua solusi lain didasarkan pada konstruksi "aman" seperti "generator nomor acak" atau "kriptografi tingkat militer", yang satu ini hanya menafsirkan string sebagai mewakili angka ganjil panjang modulo, dan menghitung invers modular mereka .
Demo:
sumber
skrip shell, 203
Menjalankannya:
Tidak terlalu portabel, tetapi dapat dibuat dengan biaya beberapa byte. Membutuhkan PGP (implementasi dengan OpenSSL juga dimungkinkan). Perbedaan ~ 50 byte antara file yang disandikan dan asli mungkin dapat disimpan.
Mencetak:
84 + abs (1659874 - 1659943) + maks (1659874 - 1660084, 0) + abs (5589891 - 5589941) + maks (5589891 - 5590284, 0) = 203
sumber
Python, skor = 183 + 7 + 6 + 0 + 0 = 196
Skor menghukum Anda karena membuat file benar-benar tidak dapat dikompresi, karena file terkompresi lebih besar dari overhead kompresi. Dengan demikian program saya membuat mereka sedikit kurang dari sama sekali tidak terkompresi:
Hasil:
sumber