Objetivo
Crie um programa ou par de programas que, coletivamente, interrompem e corrigem arquivos com o objetivo de impedir que o LZMA2 funcione efetivamente. As rotinas de interrupção e correção devem ser recíprocas, para que você possa recuperar exatamente o arquivo original.
Metas
- As obras coletadas de Shakespeare na planície UTF-8 (5.589.891 bytes)
- Imagem do Ano do Wikimedia Commons 2013 em resolução máxima (1.659.847 bytes)
Métodos de compressão
- Ubuntu / relacionados:
xz -kz5 <infile>
- Janelas:
7z.exe a -txz -mx5 <outfile> <infile>
- Outros: use um compressor LZMA2 com nível de compressão 5 que comprime os trabalhos de Shakespeare para 1570550 bytes ± 100 bytes.
Pontuação; soma de (tudo está em bytes, ls -l
ou dir
ele):
- Tamanho do programa (o que for necessário para coletivamente "quebrar" / corrigir o arquivo)
- Diferença no tamanho (absoluto) entre:
- Trabalhos coletados brutos de Shakespeare e sua cópia modificada (não compactada).
- Foto não processada e sua cópia modificada (não compactada).
- Diferença de tamanho ou 0, o que for maior entre:
- Obras coletadas em bruto de Shakespeare menos sua cópia compactada e modificada do LZMA2.
- Foto não processada menos sua cópia compactada LZMA2 modificada.
Exemplo
Exemplo de Python 2.x com pontuação baixa, golfe lento, mas compatível com:
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)
Corrida...
$ 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
Ponto
- = 194 + abs (5589891 - 5589891) + max (5589891 - 3014136, 0) + abs (1659874 - 1659874) + max (1659874 - 1646556, 0)
- = 194 + 0 + 2575755 + 0 + 13318
- 2.589.267 bytes. Ruim, mas não fazer nada nos arquivos gera uma pontuação de 4.635.153 bytes.
Esclarecimento
Isso é golfe, então você está tentando minimizar sua pontuação. Não tenho certeza se os comentários apontam um buraco legítimo na minha pontuação ou se são porque eu o tornei muito complicado. De qualquer forma, você deseja o MAIS PEQUENO :
- Código fonte
- diferença entre o arquivo modificado não compactado e o arquivo original (por exemplo, se você o modificar anexando um trilhão de zeros no final, sua pontuação aumentou um trilhão de bytes)
- diferença entre o arquivo modificado compactado e o arquivo original (por exemplo, quanto mais incompressíveis os arquivos se tornarem, maior será sua pontuação). Um arquivo perfeitamente incompressível que cresça um pouco ou não pontuará 0.
code-challenge
compression
Nick T
fonte
fonte
Respostas:
Python, pontuação = 120
Faz um bloco único usando md5 no modo contador . contém o arquivo com ele. Isso tem a vantagem de que os arquivos originais e interrompidos são do mesmo tamanho e que o disruptor e o fixador são o mesmo programa.
Os arquivos interrompidos compactados são maiores que os originais.
fonte
C, 51 = 51 + 0 + 0 + 0 + 0
Sob os truques de golfe , esse programa faz loops para cada byte na entrada padrão e é exclusivo - ou com um bloco infinito de rand (). Eu testei isso com rand () na libc do OpenBSD 5.5.
Uso:
Para testar meu programa, escrevi um shell script test.sh (57 linhas) para compilar meu programa e calcular minha pontuação.
Notas sobre rand () e o deslocamento certo
Qualquer algoritmo de compactação não pode compactar dados aleatórios. Eu posso disfarçar pg100.txt e filament.jpg como dados aleatórios se eu os embaralhar com uma cifra de fluxo .
Minha primeira idéia foi exclusiva ou texto simples com pad para criar texto cifrado e depois armazenar texto cifrado e pad no arquivo codificado. Isso aumentaria o tamanho do arquivo e aumentaria minha pontuação. A escolha óbvia é usar o mesmo bloco para cada arquivo e armazenar apenas o texto cifrado no arquivo codificado. Se eu chamar rand (), ele usa uma semente padrão de 1 e cria o mesmo bloco todas as vezes.
Openbsd 5.5 define rand () em stdlib.h e rand.c :
Este é um gerador congruencial linear . A grande falha é que bits baixos têm períodos curtos. O 1º bit tem um período de 2: se você jogar uma moeda
rand()&1
, ela vai cara, coroa, cara, coroa e assim por diante. O enésimo bit tem um período de 2 n . Existem 31 bits, portanto, toda a sequência tem um período de 2 31 .O LZMA2 pode encontrar padrões em curtos períodos e compactá-los. O código mais curto
~c^rand()
pega os 8 bits baixos e não impede a compactação. A mudança certa~c^rand()>>9
ajuda, mas não o suficiente. Eu uso~c^rand()>>23
.~c
PONTUAÇÃO: 4227957 = 40 + 0 + 0 + 4019391 + 208526~c^rand()
PONTUAÇÃO: 2474616 = 47 + 0 + 0 + 2463735 + 10834~c^rand()>>9
PONTUAÇÃO: 350717 = 50 + 0 + 0 + 350667 + 0~c^rand()>>23
PONTUAÇÃO: 51 = 51 + 0 + 0 + 0 + 0fonte
BrainFuck : 129 (129 + 0 + 0 + 0 + 0) *
random.bf (feeds de linha adicionados para facilitar a leitura)
Para criar,
unrandom.bf
você precisa alterar o último + na segunda linha.A maior parte do código é baseada no gerador de números aleatórios baseado em Rule30 de Daniel B Cristofani, adaptado para adicionar o número a cada entrada e terminar quando não houver mais entrada.
* Testei os bytes processados até o momento 212992 (processados após 12 horas) e os dois arquivos se transformam em um arquivo compactado 213064. Eu acho que isso pode ser feito até o final da semana, com certeza, mas eu não quero esperar com a postagem. Atualizo a pontuação se estiver errado, mas mantenha a solução, já que a Rule30 é excelente!
Curiosidades: A regra 30 foi descoberta por Stephen Wolfram em 1983 e, segundo a Wikipedia, é usada para produzir números inteiros aleatórios no Mathematica.
Compilação e execução:
Ele usa tempo e espaço exponenciais (itera mais de 32 células por caractere processado), portanto, requer um tempo de execução do BrainFuck que tenha pelo menos 178.876.517 células para codificar o arquivo Shakespear, não trate não ascii como unicode, tenha mais de 8 bits e use -1 como eof (para diferir entre 255 e -1). Eu costumo usar intérpretes de outras pessoas, mas desta vez eu preciso ser um plug e promover o meu:
O jitfb compila o BrainFuck para C otimizado e abusa do perl Inline :: C para executá-lo. Está incluído no meu compilador Extended BrainFuck . Com o tamanho e a largura da célula no argumento, ele alocará cerca de 400 MB.
fonte
CJam, 22 bytes
Isso usa um gerador de Fibonacci atrasado com relação de recorrência s n = (s n-5 + s n-16 )% 255 (que eu selecionei por engano, mas funciona mesmo assim) e uma semente trivial para gerar um fluxo pseudo-aleatório de bytes , que então XORs com a entrada.
Testei meu código com o CJam 0.6 , publicado em 1 de maio de 2014.
Como funciona
Ponto
fonte
PHP, 117 + 0 + 0 + 0 + 0 = 117
Porque você realmente confiaria a tarefa de manipular seus dados além do reconhecimento para qualquer outro idioma?
Enquanto todas as outras soluções são baseadas em construções "seguras", como "geradores de números aleatórios" ou "criptografia de nível militar", esta simplesmente interpreta as strings como representando números ímpares com comprimento de módulo de ⋅256 ^ e calcula seu inverso modular .
Demo:
fonte
shell script, 203
Executando:
Não é muito portátil, mas pode ser fabricado à custa de alguns bytes. Requer PGP (uma implementação com OpenSSL também seria possível). A diferença de ~ 50 bytes entre o arquivo codificado e o original provavelmente pode ser salva.
Pontuação:
84 + abs (1659874 - 1659943) + max (1659874 - 1660084, 0) + abs (5589891 - 5589941) + max (5589891 - 5590284, 0) = 203
fonte
Python, pontuação = 183 + 7 + 6 + 0 + 0 = 196
A pontuação o penaliza por tornar o arquivo completamente descompactável, desde então o arquivo compactado é maior do que a sobrecarga da compactação. Assim, meu programa os torna um pouco menos do que totalmente descompactáveis:
Resultado:
fonte