Thwart LZMA2 sıkıştırması


11

Hedef

LZMA2'nin etkin bir şekilde çalışmasını önlemek amacıyla dosyaları toplu olarak bozan ve düzelten bir program veya program çifti oluşturun. Bozukluk ve düzeltme rutinleri karşılıklı olmalıdır, böylece orijinal dosyayı tam olarak kurtarabilirsiniz.

Hedefler

Sıkıştırma Yöntemleri

  • Ubuntu / related: xz -kz5 <infile>
  • Pencereler: 7z.exe a -txz -mx5 <outfile> <infile>
  • Diğer: Shakespeare'in çalışmalarını 1570550 bayt ± 100 bayta sıkıştıran sıkıştırma seviyesi 5 olan bir LZMA2 kompresör kullanın.

puanlama; toplamı (her şey bayt cinsinden ls -lveya dirbu):

  • Program boyutu (geri döndürülebilir biçimde "kırmak" / düzeltmek için toplu olarak ne gerekiyorsa yapın)
  • Arasındaki fark (mutlak):
    • Shakespeare'in toplanan ham eserleri ve değiştirilmiş (sıkıştırılmamış) kopyanız.
    • Ham fotoğraf ve değiştirilmiş (sıkıştırılmamış) kopyanız.
  • Aşağıdakiler arasında daha büyük olan boyut veya 0 farkı:
    • Shakespeare'in ham toplanmış eserleri, değiştirilmiş LZMA2 sıkıştırılmış kopyanız.
    • Ham fotoğraf eksi değiştirilmiş, LZMA2 sıkıştırılmış kopya.

Misal

Düşük puan alan, tembel golf oynayan ancak uyumlu Python 2.x örneği:

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)

Çalıştırılıyor ...

$ 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

Puan

  • = 194 + abs (5589891 - 5589891) + max (5589891 - 3014136, 0) + abs (1659874 - 1659874) + max (1659874 - 1646556, 0)
  • = 194 + 0 + 2575755 + 0 + 13318
  • 2,589,267 bayt. Kötü, ancak dosyalara hiçbir şey yapmamak 4.635.153 baytlık bir puan verir.

açıklama

Bu golf, bu yüzden puanınızı en aza indirmeye çalışıyorsunuz . Yorumların puanlamamda meşru bir deliğe işaret edip etmediğinden veya çok karmaşık yaptığımdan emin olup olmadığından emin değilim. Her durumda, KÜÇÜK :

  • kaynak kodu
  • sıkıştırılmamış değiştirilmiş dosya ile orijinal dosya arasındaki fark (örneğin, sonuna bir trilyon 0 ekleyerek değiştirirseniz, puanınız bir trilyon bayta yükseldi)
  • sıkıştırılmış değiştirilmiş dosya ile orijinal dosya arasındaki fark (örneğin, dosyalar ne kadar sıkıştırılamaz olursa puanınız o kadar yüksek olur). Biraz büyüyen veya hiç büyümeyen mükemmel sıkıştırılamaz bir dosya 0 puan alır.

2
Trolling cevabı: Adım 1 - ne kadar boş disk alanınız olduğunu çalışın ve N'yi elde etmek için dosyanın boyutuna bölün. Adım 2 - dosyayı N kere ekleyin ve N sayısını ekleyin. Adım 3 - orada olduğunu anlayın dosyayı sıkıştırmak için boşluk kalmadı, ancak birkaç terabaytın (veya daha fazlasının) dosya boyutlarında mutlak bir farkla sonuçlandı .... [Geri almak için, dosyanın sonundan N'yi okuyun ve dosyayı 1 / Nth boyutuna küçültün. ]
MT0

MT0 @: Ah ben çözüm farklılıkları gerektiğini düşünüyorum değil mutlak olun. Değiştirilmiş dosyanız daha büyükse, puanları çıkarmanız gerekir.
Claudiu

@ MT0 Dosyayı terabayt büyük olacak şekilde değiştirirseniz, golf oynamaya çalışırken skorunuz 1 terabayt ... oldukça kötü olacaktır.
Nick T

@ MT0 Gönderiye bir açıklama ekledim, bu yardımcı olur mu?
Nick T

2
Bir kelime oyunu. T özellikle sıkıştırılamazsa kompresör daha büyük bir dosya oluşturabilir. Bu durumda ödüllendirilmeli, cezalandırılmamalı, değil mi?
Claudiu

Yanıtlar:


8

Python, skor = 120

import sys,hashlib
i=0
for c in sys.stdin.read():sys.stdout.write(chr(ord(c)^ord(hashlib.md5(str(i)).digest()[0])));i+=1

Sayaç modunda md5 kullanarak bir kerelik bir ped yapar . xors onunla dosya. Bu, orijinal ve bozulmuş dosyaların aynı boyutta olması ve disruptor ve fixer'ın aynı program olması avantajına sahiptir.

Sıkıştırılmış bozulan dosyalar orijinallerden daha büyüktür.


Sıkıştırılmış dosyalar varsa o kadar gol düzeltilmiş büyük sen cezalandırmaz orijinal meslektaşlarının daha ve onlar sadece 0'a puanı emin değil fark dosyalarınız için ama sen skor güncellemek isteyebilirsiniz hangi yöne
Nick T

@NickT: güncellendi.
Keith Randall

8

C, 51 = 51 + 0 + 0 + 0 + 0

main(c){for(;c=~getchar();putchar(~c^rand()>>23));}

Golf hileleri altında , bu program standart girdi içindeki her bayt için döngüler ve özel - veya rand () sonsuz bir pad ile yapar. Bunu OpenBSD 5.5 libc içinde rand () ile test ettim.

Kullanımı:

./scramble <orig >scrambled
./scramble <scrambled >orig.copy

Programımı test etmek için, programımı derlemek ve puanımı hesaplamak için bir shell script test.sh (57 satır) yazdım.

$ sh test.sh
[1/4] Compiling scramble...
/tmp//ccbcB43x.o(.text+0x6): In function `main':
: warning: rand() isn't random; consider using arc4random()
[2/4] Scrambling files...
[3/4] Compressing scrambled files...
[4/4] Checking descrambler...
SCORE: 51=51+0+0+0+0
You may wish to rm -rf tmp.9Tjw89dgCs
$ ls -l tmp.9Tjw89dgCs/
total 43032
-rw-r--r--  1 kernigh  kernigh  1659874 May 28 17:23 filament.jpg.cp
-rw-r--r--  1 kernigh  kernigh  1659874 May 28 17:23 filament.jpg.sc
-rw-r--r--  1 kernigh  kernigh  1660016 May 28 17:23 filament.jpg.sc.xz
-rw-r--r--  1 kernigh  kernigh  5589891 May 28 17:23 pg100.txt.cp
-rw-r--r--  1 kernigh  kernigh  5589891 May 28 17:23 pg100.txt.sc
-rw-r--r--  1 kernigh  kernigh  5590232 May 28 17:23 pg100.txt.sc.xz
-rwxr-xr-x  1 kernigh  kernigh     8564 May 28 17:23 scramble

Rand () ve doğru vardiya hakkında notlar

Herhangi bir sıkıştırma algoritması rastgele verileri sıkıştıramaz. Bir akış şifresiyle karıştırırsam pg100.txt ve filament.jpg dosyasını rastgele veri olarak gizleyebilirim .

Benim ilk fikir dışlamalı veya etmekti düz metin ile ped markası için şifreli sonra hem saklamak, şifreli ve pedi şifreli dosyada. Bu dosyanın boyutunu artıracak ve puanımı artıracaktır. Açık seçim, her dosya için aynı paneli kullanmak ve şifrelenmiş dosyada yalnızca şifreli metni depolamaktır . Sadece rand () çağırırsam, varsayılan 1 tohum kullanır ve her seferinde aynı pedi yapar .

OpenBSD 5.5, stdlib.h ve rand.c dosyasında rand () öğesini tanımlar :

/* from stdlib.h */
#define RAND_MAX    0x7fffffff

/* from rand.c */
static u_int next = 1;

int
rand_r(u_int *seed)
{
    *seed = *seed * 1103515245 + 12345;
    return (*seed % ((u_int)RAND_MAX + 1));
}

int
rand(void)
{
    return (rand_r(&next));
}

Bu doğrusal bir doğuştan üretecidir . Büyük kusur, düşük bitlerin kısa süreler olmasıdır. 1. bitin 2 periyodu vardır: bir madeni para ile çevirirseniz rand()&1, kafalara, kuyruklara, kafalara, kuyruklara vb. Gider. N'inci bitin süresi 2 n'dir . 31 bit vardır, bu nedenle tüm dizinin süresi 2 31'dir .

LZMA2 desenleri kısa sürede bulabilir ve sıkıştırabilir. En kısa kod ~c^rand()düşük 8 biti alır ve sıkıştırmayı engellemez. Doğru vardiya ~c^rand()>>9yardımcı olur, ancak yeterli değildir. Ben kullanıyorum ~c^rand()>>23.

  • ~c PUAN: 4227957 = 40 + 0 + 0 + 4019391 + 208526
  • ~c^rand() PUAN: 2474616 = 47 + 0 + 0 + 2463735 + 10834
  • ~c^rand()>>9 PUAN: 350717 = 50 + 0 + 0 + 350667 + 0
  • ~c^rand()>>23 PUAN: 51 = 51 + 0 + 0 + 0 + 0

5

BrainFuck : 129 (129 + 0 + 0 + 0 + 0) *

random.bf (okunabilirlik için satır beslemeleri eklendi)

,+[->>>>++[<++++++++[<[<++>-]>>[>>]+>>+[-[->>+<<<[<[<<]<
+>]>[>[>>]]]<[>>[-]]>[>[-<<]>[<+<]]+<<]<[>+<-]>>-]<[-<<+
>>]<<.,+[->]>>>]]

Oluşturmak unrandom.bfiçin ikinci satırdaki son + işaretini değiştirmeniz gerekir.

Kodun çoğu Daniel B Cristofani'nin her bir girişe sayı eklemek ve daha fazla giriş olmadığında sonlandırmak için uyarlanmış Rule30 tabanlı rastgele sayı üretecini temel alır .

* Şimdiye kadar işlenen baytları test ettim 212992 (12 saat sonra işlendi) ve her iki dosya da 213064 sıkıştırılmış bir dosyaya dönüşüyor. Herhalde bunu bilmek için haftanın sonuna kadar yapılabilir ama ben gönderme ile beklemek istemiyorum. Yanlışsa skoru güncelleyeceğim, ancak Rule30 sallandığından beri çözümü koruyacağım!

Diğer bilgiler: Kural 30 , 1983 yılında Stephen Wolfram tarafından keşfedildi ve Wikipedia'ya göre Mathematica'da rastgele tamsayılar üretmek için kullanıldı.

Derleme ve çalıştırma:

Üstel zaman ve alan kullanır (işlenen karakter başına 32'den fazla hücre tekrarlar), bu nedenle Shakespear dosyasını kodlamak, ascii olmayanları unicode olarak ele almamak, 8 bitten daha geniş hücrelere ve kullanımlara sahip olmak için en az 178,876,517 hücreye sahip bir BrainFuck çalışma zamanı gerektirir. -1 olarak (255 ile -1 arasında). Genellikle başkalarının halk tercümanlarını kullanıyorum ama bu sefer bir fiş olmak ve kendimi tanıtmak gerekiyor:

jitbf --eof -1 -b 16 -c 200000000 random.bf < pg100.txt > pg100.txt.ran
jitbf --eof -1 -b 16 -c 200000000 random.bf < Glühwendel_brennt_durch.jpg > Glühwendel_brennt_durch.jpg.ran

jitfb, BrainFuck'ı optimize edilmiş C'ye derler ve çalıştırmak için perl Inline :: C'yi kötüye kullanır. Benim ile demetleri Genişletilmiş brainfuck derleyici . Argümandaki hücre boyutu ve genişliği yaklaşık 400 MB ayıracaktır.


3

CJam, 22 bayt

G,~q{5$H$+255%_@^o}/];

Bu, tekrarlama ilişkisi s n = (s n-5 + s n-16 olan gecikmeli bir Fibonacci jeneratörü kullanır )% 255 (yanlışlıkla seçtim, ancak yine de çalışır) ve sahte rastgele bir bayt akışı oluşturmak için önemsiz bir tohum kullanır daha sonra girişle birlikte XOR'lar.

Kodumu test ettim Kodumu 1 Mayıs 2014'te yayınlanan CJam 0.6 .

Nasıl çalışır

G,~                    e# Dump 0, 1, ... and 15 on the stack.
   q                   e# Read from STDIN.
    {             }/   e# For each character in the input.
     5$H$              e# Copy the sixth and 19th element from the stack.
         +255%         e# Push their sum modulo 255.
              _@       e# Duplicate and rotate the character on top.
                ^o     e# XOR and print.
                    ]; e# Clear the stack.

Puan

$ LANG=en_US
$ alias cjam='java -jar /usr/local/share/cjam/cjam-0.6.jar'
$ cjam thwart.cjam < pg100.txt > pg100.txt~
$ cjam thwart.cjam < pg100.txt~ > pg100.txt~~
$ diff -s pg100.txt pg100.txt~~
Files pg100.txt and pg100.txt~~ are identical
$ cjam thwart.cjam < Gluehwendel_brennt_durch.jpg > Gluehwendel_brennt_durch.jpg~
$ cjam thwart.cjam < Gluehwendel_brennt_durch.jpg~ > Gluehwendel_brennt_durch.jpg~~
$ diff -s Gluehwendel_brennt_durch.jpg Gluehwendel_brennt_durch.jpg~~
Files Gluehwendel_brennt_durch.jpg and Gluehwendel_brennt_durch.jpg~~ are identical
$ xz -kz5 pg100.txt~ Gluehwendel_brennt_durch.jpg~
$ wc -c thwart.cjam pg100.txt* Gluehwendel_brennt_durch.jpg*
      22 thwart.cjam
 5589889 pg100.txt
 5589889 pg100.txt~
 5589889 pg100.txt~~
 5590232 pg100.txt~.xz
 1659874 Gluehwendel_brennt_durch.jpg
 1659874 Gluehwendel_brennt_durch.jpg~
 1659874 Gluehwendel_brennt_durch.jpg~~
 1660016 Gluehwendel_brennt_durch.jpg~.xz
28999559 total

3

PHP, 117 + 0 + 0 + 0 + 0 = 117

Çünkü verilerinizi başka bir dile tanınmanın ötesinde yönetme görevini gerçekten emanet eder misiniz?

<?=substr(gmp_export(gmp_invert(2*gmp_import($s=stream_get_contents(STDIN))+1,$m=2*gmp_pow(256,strlen($s)))/2+$m),1);

Diğer tüm çözümler “rasgele sayı üreteçleri” veya “askeri sınıf kriptografi” gibi “güvenli” yapılara dayandırılırken, bu sadece dizeleri tek sayı modulo 2⋅256 ^ uzunluğunu temsil eden olarak yorumlar ve modüler tersini hesaplar .

Demo:

$ php thwart.php < 100.txt.utf-8 > 100.txt.utf-8~
$ php thwart.php < 100.txt.utf-8~ > 100.txt.utf-8~~
$ diff -s 100.txt.utf-8 100.txt.utf-8~~
Files 100.txt.utf-8 and 100.txt.utf-8~~ are identical
$ php thwart.php < Glühwendel_brennt_durch.jpg > Glühwendel_brennt_durch.jpg~
$ php thwart.php < Glühwendel_brennt_durch.jpg~ > 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 100.txt.utf-8~ Glühwendel_brennt_durch.jpg~
$ wc -c *
 5589889 100.txt.utf-8
 5589889 100.txt.utf-8~
 5590232 100.txt.utf-8~.xz
 5589889 100.txt.utf-8~~
 1659874 Glühwendel_brennt_durch.jpg
 1659874 Glühwendel_brennt_durch.jpg~
 1660016 Glühwendel_brennt_durch.jpg~.xz
 1659874 Glühwendel_brennt_durch.jpg~~
     117 thwart.php
28999654 total

2

kabuk betiği, 203

id|gpg --batch --passphrase-fd 0 --personal-compress-preferences Uncompressed $1 $2

Koşu:

% sh break.sh -c pg100.txt                       
% sh break.sh -d pg100.txt.gpg > pg100.txt-original
gpg: CAST5 encrypted data
gpg: encrypted with 1 passphrase
gpg: WARNING: message was not integrity protected
% diff -s pg100.txt pg100.txt-original
Files pg100.txt and pg100.txt-original are identical
% sh break.sh -c Glühwendel_brennt_durch.jpg
% sh break.sh -d Glühwendel_brennt_durch.jpg.gpg > Glühwendel_brennt_durch.jpg-original
gpg: CAST5 encrypted data
gpg: encrypted with 1 passphrase
gpg: WARNING: message was not integrity protected
% diff -s Glühwendel_brennt_durch.jpg Glühwendel_brennt_durch.jpg-original
Files Glühwendel_brennt_durch.jpg and Glühwendel_brennt_durch.jpg-original are identical
% xz -kz5 Glühwendel_brennt_durch.jpg.gpg 
% xz -kz5 pg100.txt.gpg 
% ls -ln
total 28340
-rw-r--r-- 1 1000 1000      84 May 24 04:33 break.sh
-rw-r--r-- 1 1000 1000 1659874 Jan 19 17:22 Glühwendel_brennt_durch.jpg
-rw-r--r-- 1 1000 1000 1659943 May 24 04:46 Glühwendel_brennt_durch.jpg.gpg
-rw-r--r-- 1 1000 1000 1660084 May 24 04:46 Glühwendel_brennt_durch.jpg.gpg.xz
-rw-r--r-- 1 1000 1000 1659874 May 24 04:46 Glühwendel_brennt_durch.jpg-original
-rw-r--r-- 1 1000 1000 5589891 May 24 03:55 pg100.txt
-rw-r--r-- 1 1000 1000 5589941 May 24 04:43 pg100.txt.gpg
-rw-r--r-- 1 1000 1000 5590284 May 24 04:43 pg100.txt.gpg.xz
-rw-r--r-- 1 1000 1000 5589891 May 24 04:43 pg100.txt-original

Çok taşınabilir değil, ama birkaç bayt pahasına yapılabilir. PGP gerektirir (OpenSSL ile bir uygulama da mümkündür). Kodlanmış dosya ile orijinal arasındaki ~ 50 baytlık fark muhtemelen kaydedilebilir.

puanlama:

84 + abs (1659874 - 1659943) + maks. (1659874 - 1660084, 0) + abs (5589891 - 5589941) + maks. (5589891 - 5590284, 0) = 203


1

Python, skor = 183 + 7 + 6 + 0 + 0 = 196

Puanlama, dosyayı tamamen sıkıştırılamaz yaptığınız için cezalandırır, çünkü sıkıştırılmış dosya sıkıştırma yükünden daha büyüktür. Böylece benim program onları tamamen sıkıştırılamaz biraz daha az yapar:

import sys
from random import randint as J,seed
x=sys.stdin.read()
seed(ord(x[1]))
n=int(2362*J(1,2)**2.359)
sys.stdout.write(x[:n]+''.join(chr(ord(c)^J(0,255))for c in x[n:]))

Sonuç:

Laxori@Laxori-PC /cygdrive/f/Programming/lzkill
$ cat photo.jpg | python break.py > photo.jpg~; cat photo.jpg~ | python break.py > photo.jpg~~; diff photo.jpg photo.jpg~~; xz -kz5 photo.jpg~

Laxori@Laxori-PC /cygdrive/f/Programming/lzkill
$ cat pg100.txt | python break.py > pg100.txt~; cat pg100.txt~ | python break.py > pg100.txt~~; diff pg100.txt pg100.txt~~; xz -kz5 pg100.txt~

Laxori@Laxori-PC /cygdrive/f/Programming/lzkill
$ ls -l
total 28337
----------+ 1 Laxori mkpasswd     183 2014-05-24 13:43 break.py
----------+ 1 Laxori mkpasswd 5589891 2014-05-23 19:19 pg100.txt
-rw-r--r--+ 1 Laxori mkpasswd 5589891 2014-05-24 13:45 pg100.txt~
-rw-r--r--+ 1 Laxori mkpasswd 5589884 2014-05-24 13:45 pg100.txt~.xz
-rw-r--r--+ 1 Laxori mkpasswd 5589891 2014-05-24 13:45 pg100.txt~~
----------+ 1 Laxori mkpasswd 1659874 2014-05-23 19:19 photo.jpg
-rw-r--r--+ 1 Laxori mkpasswd 1659874 2014-05-24 13:44 photo.jpg~
-rw-r--r--+ 1 Laxori mkpasswd 1659880 2014-05-24 13:44 photo.jpg~.xz
-rw-r--r--+ 1 Laxori mkpasswd 1659874 2014-05-24 13:44 photo.jpg~~

Laxori@Laxori-PC /cygdrive/f/Programming/lzkill
$ python
Python 2.5.2 (r252:60911, Dec  2 2008, 09:26:14)
[GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 183 + abs(5589891-5589884) + abs(1659874-1659880)
196

Mevcut kurallarda, sıkıştırılmış bir dosyanın daha büyük olması için herhangi bir ceza yoktur. Kurallar değişti mi? Eğer öyleyse, böyle bir değişiklik bu program için haksızdı.
kernigh

@kernigh: Evet, gönderdikten sonra değiştiler. Gerçekten de en başından beri oldukları gibi olmalıydılar.
Claudiu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.