LZMA2圧縮を阻止する


11

ゴール

LZMA2が効果的に機能しないように、ファイルをまとめて中断および修正するプログラムまたはプログラムのペアを作成します。中断および修正ルーチンは相互に関係する必要があるため、元のファイルを正確に回復できます。

対象

圧縮方法

  • Ubuntu /関連: xz -kz5 <infile>
  • ウィンドウズ: 7z.exe a -txz -mx5 <outfile> <infile>
  • その他:シェークスピアの作品を1570550バイト±100バイトに圧縮する圧縮レベル5のLZMA2コンプレッサーを使用します。

得点; 合計(すべてはバイト単位、ls -lまたはdirそれ):

  • プログラムのサイズ(ファイルを可逆的に「ブレイク」/修正するために必要なもの)
  • 次のサイズの差(絶対):
    • シェークスピアの未加工の収集作品と、修正された(非圧縮の)コピー。
    • 未加工の写真と変更した(非圧縮)コピー。
  • サイズの差または0のいずれか大きい方:
    • シェークスピアの未加工の収集作品から、修正されたLZMA2圧縮コピーを差し引いたもの。
    • 生の写真から変更したLZMA2圧縮コピーを差し引いたもの。

スコアが低く、怠laなゴルフだが、Python 2.xに準拠した例:

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)

ランニング...

$ 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

スコア

  • = 194 + abs(5589891 − 5589891)+ 最大(5589891 − 3014136、0)+ abs(1659874 − 1659874)+ 最大(1659874 − 1646556、0)
  • = 194 + 0 + 2575755 + 0 + 13318
  • 2,589,267バイト。 悪いですが、ファイルに何もしないと、スコアは4,635,153バイトになります。

明確化

これはゴルフなので、スコアを最小化しようとしています。コメントが私の得点の正当な穴を指摘しているのか、それとも私があまりにも複雑にしたためかどうかはわかりません。いずれにせよ、あなたは最小が欲しい:

  • ソースコード
  • 圧縮されていない変更されたファイルと元のファイルの違い(たとえば、末尾に1兆の0を追加して変更すると、スコアは1兆バイト増加しました)
  • 圧縮された変更済みファイルと元のファイルの違い(たとえば、ファイルの圧縮率が高くなるほど、スコアが高くなります)。わずかに成長する、またはまったく成長しない完全に非圧縮性のファイルは0になります。

2
トローリングの答え:ステップ1-どれだけの空きディスク容量があるかを計算し、それをファイルのサイズで割ってNを取得します。ステップ2-ファイルを自分自身にN回追加し、数Nを追加します。ファイルを圧縮するためのスペースは残っていませんが、数テラバイト(またはそれ以上)のファイルサイズに絶対差があります... [逆にするには、ファイルの末尾からNを読み取り、サイズを1 / Nに縮小します。 ]
MT0

@ MT0:ああ、解決策は絶対的な違いではないだろうと思います。変更したファイルが大きい場合は、ポイントを差し引く必要があります。
クラウディウ

@ MT0ファイルを修正して1テラバイトの大きさにすると、スコアは1テラバイトになります...ゴルフをしようとするとかなり悪くなります。
ニックT

@ MT0投稿に説明を追加しましたが、それは役に立ちますか?
ニックT

2
一。tが特に圧縮できない場合、圧縮プログラムはより大きなファイルを作成する場合があります。この場合、罰せられるのではなく、報われるべきですか?
クラウディウ

回答:


8

Python、スコア= 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

カウンターモードで md5を使用してワンタイムパッドを作成します。ファイルをxorsします。これには、元のファイルと中断されたファイルが同じサイズであり、中断と修正プログラムが同じプログラムであるという利点があります。

圧縮された中断ファイルは、元のファイルよりも大きくなります。


ZIPファイルがある場合、私はそう得点調整さより大きいあなたが罰せされていない元の対応よりも、彼らは単に0を獲得わからないの違いは、あなたのファイルのためだったが、あなたはスコア更新したいことがある方法
ニック・T

@NickT:更新されました。
キースランドール

8

C、51 = 51 + 0 + 0 + 0 + 0

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

下ではゴルフのトリック、このプログラムは、標準入力の各バイトのためのループ、および排他的論理和ランドから無限パッド()で行います。OpenBSD 5.5のlibcのrand()でこれをテストしました。

使用法:

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

プログラムをテストするため、シェルスクリプトtest.sh(57行)を作成してプログラムをコンパイルし、スコアを計算しました。

$ 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()と右シフトに関する注意

圧縮アルゴリズムは、ランダムデータを圧縮できません。ストリーム暗号でスクランブルをかけると、pg100.txtフィラメント.jpgをランダムなデータとして偽装できます。

私の最初のアイデアは、排他的またはパッド付きの平文暗号文を作成し、暗号化されたファイルに暗号文パッドの両方を保存することでした。これにより、ファイルのサイズが大きくなり、スコアが増加します。明白な選択は、すべてのファイルに同じパッドを使用し、暗号化されたテキストのみをスクランブルファイルに保存することです。rand()を呼び出すだけで、デフォルトのシード1が使用され、毎回同じパッドが作成されます。

OpenBSD 5.5はstdlib.hおよびrand.cでrand()を定義しています

/* 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));
}

これは線形合同ジェネレータです。大きな欠点は、低ビットの期間が短いことです。1番目のビットの周期は2です。でコインを反転するとrand()&1、頭、尾、頭、尾などになります。n番目のビットの周期は2 nです。31ビットがあるため、シーケンス全体の周期は2 31です。

LZMA2は、短時間でパターンを見つけて圧縮できます。最短のコード~c^rand()は下位8ビットを使用し、圧縮を妨げません。正しいシフトは~c^rand()>>9役立ちますが、十分ではありません。を使用します~c^rand()>>23

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

5

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

random.bf(読みやすくするために改行が追加されました)

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

作成unrandom.bfするには、2行目の最後の+を変更する必要があります。

ほとんどのコードは、各入力に番号を追加し、入力がなくなったときに終了するように構成されたダニエルBクリストファニRule30ベースの乱数ジェネレータに基づいています。

*これまでに処理したバイト数をテストしました(212992(12時間後に処理))。両方のファイルが213064圧縮ファイルになります。確かにそれは週の終わりまでに行われるかもしれないと思いますが、投稿を待ちたくありません。スコアが間違っている場合はスコアを更新しますが、Rule30が揺れるので解決策を維持します!

雑学:ルール30は1983年にStephen Wolframによって発見され、Wikipediaによると、Mathematicaでランダムな整数を生成するために使用されています。

コンパイルと実行:

指数関数的な時間と空間を使用するため(処理される文字ごとにさらに32個以上のセルを繰り返す)、シェークスピアファイルをエンコードするために少なくとも178,876,517個のセルを含むBrainFuckランタイムが必要です。 eofとして-1(255と-1の間で異なる)。私は通常、他の人々の通訳を使用しますが、今回はプラグインになり、自分の通訳をする必要があります。

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を最適化されたCにコンパイルし、perl Inline :: Cを悪用して実行します。Extended BrainFuckコンパイラーのバンドルです。引数にセルのサイズと幅を指定すると、約400MBが割り当てられます。


3

CJam、22バイト

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

これは、再帰関係s n =(s n-5 + s n-16)%255(これは間違って選択しましたが、それでも動作します)とバイトの擬似ランダムストリームを生成するための簡単なシードを使用した遅延フィボナッチジェネレーターを使用します、入力とXORします。

2014年5月1日に公開されたCJam 0.6でコードをテストしました。

使い方

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.

スコア

$ 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

なぜなら、他の言語の認識を超えてデータをマングリングするタスクを本当に委ねるのですか?

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

他のすべてのソリューションは、「乱数ジェネレーター」や「軍事グレードの暗号化」などの「安全な」構造に基づいていますが、これは単に文字列を2⋅256^ lengthを法とする奇数を表すものとして解釈し、モジュラー逆数を計算します。

デモ:

$ 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

シェルスクリプト、203

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

実行する:

% 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

あまりポータブルではありませんが、数バイトのコストで作成できます。PGPが必要です(OpenSSLを使用した実装も可能です)。エンコードされたファイルと元のファイル間の最大50バイトの差はおそらく保存できます。

得点:

84 + abs(1659874-1659943)+ max(1659874-1660084、0)+ abs(5589891-5589941)+ max(5589891-5590284、0)= 203


1

Python、スコア= 183 + 7 + 6 + 0 + 0 = 196

スコアリングは、圧縮されたファイルが圧縮オーバーヘッドよりも大きいため、ファイルを完全に非圧縮可能にすることに対してペナルティを科します。したがって、私のプログラムはそれらを完全に非圧縮性よりもわずかに少なくします:

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:]))

結果:

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

現在のルールでは、圧縮ファイルが大きくなってもペナルティはありません。ルールは変更されましたか?もしそうなら、そのような変更はこのプログラムにとって不公平でした。
カーニグ

@kernigh:投稿後に変更されました。本当に、彼らは最初から彼らが今のようになっているべきだった。
クラウディウ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.