Tor
Erstellen Sie ein Programm oder ein Programmpaar, das gemeinsam Dateien stört und repariert, um zu verhindern, dass LZMA2 effektiv funktioniert. Die Unterbrechungs- und Korrekturroutinen müssen wechselseitig sein, damit Sie die Originaldatei genau wiederherstellen können.
Ziele
- Die gesammelten Werke von Shakespeare in einfachem UTF-8 (5.589.891 Bytes)
- Wikimedia Commons 2013 Bild des Jahres in voller Auflösung (1.659.847 Bytes)
Komprimierungsmethoden
- Ubuntu / verwandt:
xz -kz5 <infile>
- Windows:
7z.exe a -txz -mx5 <outfile> <infile>
- Sonstiges: Verwenden Sie einen LZMA2-Kompressor mit Komprimierungsstufe 5, der die Werke von Shakespeare auf 1570550 Byte ± 100 Byte komprimiert.
Wertung; Summe von (alles ist in Bytes ls -l
oder dir
so):
- Programmgröße (was auch immer zusammen benötigt wird, um die Datei reversibel zu "brechen" / zu reparieren)
- Größenunterschied (absolut) zwischen:
- Rohe gesammelte Werke von Shakespeare und Ihre modifizierte (unkomprimierte) Kopie.
- Rohfoto und Ihre modifizierte (unkomprimierte) Kopie.
- Größenunterschied oder 0, je nachdem, welcher Wert größer ist zwischen:
- Rohe gesammelte Werke von Shakespeare abzüglich Ihrer modifizierten, LZMA2-komprimierten Kopie.
- Rohfoto abzüglich Ihrer modifizierten, LZMA2-komprimierten Kopie.
Beispiel
Schlecht punktendes, träge Golf, aber konformes Python 2.x-Beispiel:
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)
Laufen...
$ 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
Ergebnis
- = 194 + abs (5589891 - 5589891) + max (5589891 - 3014136, 0) + abs (1659874 - 1659874) + max (1659874 - 1646556, 0)
- = 194 + 0 + 2575755 + 0 + 13318
- 2,589,267 Bytes. Schlecht, aber nichts mit den Dateien zu tun, ergibt eine Punktzahl von 4.635.153 Bytes.
Klärung
Dies ist Golf, also versuchen Sie, Ihre Punktzahl zu minimieren . Ich bin mir nicht sicher, ob die Kommentare auf ein legitimes Loch in meiner Wertung hinweisen oder ob sie es sind, weil ich es zu kompliziert gemacht habe. In jedem Fall möchten Sie das KLEINSTE :
- Quellcode
- Unterschied zwischen der unkomprimierten geänderten Datei und der Originaldatei (z. B. wenn Sie sie ändern, indem Sie am Ende eine Billion Nullen anhängen, ist Ihre Punktzahl nur um eine Billion Bytes gestiegen)
- Unterschied zwischen der komprimierten modifizierten Datei und der Originaldatei (z. B. je inkompressibler die Dateien werden, desto höher ist Ihre Punktzahl). Eine perfekt inkompressible Datei, die leicht oder gar nicht wächst, erhält 0 Punkte.
code-challenge
compression
Nick T.
quelle
quelle
Antworten:
Python, Punktzahl = 120
Erstellt ein einmaliges Pad mit md5 im Zählermodus . xors die Datei damit. Dies hat den Vorteil, dass die ursprüngliche und die gestörte Datei dieselbe Größe haben und dass der Störer und der Fixierer dasselbe Programm haben.
Die komprimierten gestörten Dateien sind größer als die Originale.
quelle
C, 51 = 51 + 0 + 0 + 0 + 0
Unter den Golf-Tricks durchläuft dieses Programm jedes Byte in der Standardeingabe und wird exklusiv ausgeführt - oder mit einem unendlichen Pad von rand (). Ich habe dies mit rand () in libc von OpenBSD 5.5 getestet.
Verwendung:
Um mein Programm zu testen, habe ich ein Shell-Skript test.sh (57 Zeilen) geschrieben , um mein Programm zu kompilieren und meine Punktzahl zu berechnen.
Hinweise zu rand () und der Rechtsverschiebung
Jeder Komprimierungsalgorithmus kann keine zufälligen Daten komprimieren. Ich kann pg100.txt und filament.jpg als zufällige Daten tarnen , wenn ich sie mit einer Stream-Verschlüsselung verschlüssele .
Meine erste Idee war, Exklusiv- oder Klartext mit Pad zu erstellen , um Chiffretext zu erstellen , und dann sowohl Chiffretext als auch Pad in der verschlüsselten Datei zu speichern. Dies würde die Größe der Datei erhöhen und meine Punktzahl erhöhen. Die naheliegende Wahl besteht darin, für jede Datei dasselbe Pad zu verwenden und nur Chiffretext in der verschlüsselten Datei zu speichern. Wenn ich nur rand () aufrufe, wird ein Standard-Startwert von 1 verwendet und jedes Mal das gleiche Pad erstellt .
OpenBSD 5.5 definiert rand () in stdlib.h und rand.c :
Dies ist ein linearer Kongruenzgenerator . Der große Fehler ist, dass niedrige Bits kurze Perioden haben. Das erste Bit hat eine Periode von 2: Wenn Sie eine Münze mit werfen
rand()&1
, geht es um Köpfe, Schwänze, Köpfe, Schwänze und so weiter. Das n-te Bit hat eine Periode von 2 n . Es gibt 31 Bits, daher hat die gesamte Sequenz eine Periode von 2 31 .LZMA2 kann Muster in kurzen Zeiträumen finden und komprimieren. Der kürzeste Code
~c^rand()
nimmt die niedrigen 8 Bits und verhindert nicht die Komprimierung. Die richtige Verschiebung~c^rand()>>9
hilft, aber nicht genug. Ich benutze~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 + 0quelle
BrainFuck : 129 (129 + 0 + 0 + 0 + 0) *
random.bf (Zeilenvorschübe zur besseren Lesbarkeit hinzugefügt)
Zum Erstellen müssen
unrandom.bf
Sie das letzte + in der zweiten Zeile ändern.Der größte Teil des Codes basiert auf dem auf Regel 30 basierenden Zufallszahlengenerator von Daniel B. Cristofani, der angepasst wurde, um die Nummer zu jeder Eingabe hinzuzufügen und zu beenden, wenn keine Eingabe mehr vorhanden ist.
* Ich habe die bisher verarbeiteten Bytes 212992 (nach 12 Stunden verarbeitet) getestet und beide Dateien werden zu einer komprimierten 213064-Datei. Ich denke, es könnte sicher bis Ende der Woche fertig sein, aber ich möchte nicht mit dem Posten warten. Ich werde die Punktzahl aktualisieren, wenn es falsch ist, aber die Lösung behalten, da Regel 30 rockt!
Wissenswertes: Regel 30 wurde 1983 von Stephen Wolfram entdeckt und laut Wikipedia verwendet, um zufällige ganze Zahlen in Mathematica zu erzeugen.
Zusammenstellung und Ausführung:
Es verwendet exponentielle Zeit und Raum (iteriert über 32 weitere Zellen pro verarbeitetem Zeichen), sodass eine BrainFuck-Laufzeit erforderlich ist, die mindestens 178.876.517 Zellen zum Codieren der Shakespear-Datei enthält, Nicht-ASCII nicht als Unicode behandelt, mehr als 8-Bit-Zellen enthält und verwendet -1 als eof (zwischen 255 und -1 zu unterscheiden). Normalerweise benutze ich Dolmetscher anderer Leute, aber dieses Mal muss ich ein Plug sein und meine eigenen fördern:
jitfb kompiliert BrainFuck zu optimiertem C und missbraucht Perl Inline :: C, um es auszuführen. Es wird mit meinem Extended BrainFuck-Compiler gebündelt . Mit der Zellengröße und -breite im Argument werden ungefähr 400 MB zugewiesen.
quelle
CJam, 22 Bytes
Dies verwendet einen verzögerten Fibonacci-Generator mit der Wiederholungsrelation s n = (s n-5 + s n-16 )% 255 (den ich versehentlich ausgewählt habe, der aber trotzdem funktioniert) und einen trivialen Startwert, um einen pseudozufälligen Strom von Bytes zu erzeugen , die es dann mit der Eingabe XORs.
Ich habe meinen Code mit CJam 0.6 getestet , das am 1. Mai 2014 veröffentlicht wurde.
Wie es funktioniert
Ergebnis
quelle
PHP, 117 + 0 + 0 + 0 + 0 = 117
Denn würden Sie wirklich die Aufgabe anvertrauen, Ihre Daten bis zur Unkenntlichkeit einer anderen Sprache zuzuordnen?
Während alle anderen Lösungen auf „sicheren“ Konstruktionen wie „Zufallszahlengeneratoren“ oder „Kryptographie in Militärqualität“ basieren, interpretiert diese einfach Zeichenfolgen als ungerade Zahlen mit einer Länge von Modulo 2⋅256 ^ und berechnet ihre modulare Inverse .
Demo:
quelle
Shell-Skript, 203
Ausführen:
Nicht sehr portabel, könnte aber auf Kosten von ein paar Bytes hergestellt werden. Benötigt PGP (eine Implementierung mit OpenSSL wäre ebenfalls möglich). Der Unterschied von ~ 50 Byte zwischen codierter Datei und Original kann wahrscheinlich gespeichert werden.
Wertung:
84 + abs (1659874 - 1659943) + max (1659874 - 1660084, 0) + abs (5589891 - 5589941) + max (5589891 - 5590284, 0) = 203
quelle
Python, Punktzahl = 183 + 7 + 6 + 0 + 0 = 196
Die Bewertung bestraft Sie dafür, dass Sie die Datei vollständig unkomprimierbar machen, da die komprimierte Datei vom Komprimierungsaufwand größer ist. Mein Programm macht sie also etwas weniger als völlig unkomprimierbar:
Ergebnis:
quelle