Variante criptográfica de quine

22

Crie um programa que imprima a soma MD5 de sua origem no formato:

MD5 sum of my source is: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Sem trapaça - você não pode simplesmente ler o arquivo de origem e calcular sua soma. O programa não deve ler nenhuma informação externa.

Claro que você pode usar uma biblioteca MD5 disponível para o seu idioma.

Petr Pudlák
fonte
1
Se alguém conseguir colidir com o MD5 (ou seja, h = f (h), onde f é um "sal" bruto para h com todo o lixo de código necessário para imprimir), acho que eles devem fazer isso.
Nick T
1
@ NickT Isso seria extremamente difícil, devo acrescentar.
PyRulez

Respostas:

13

Python 157 149

r='r=%r;import md5;print "MD5 sum of my source is: "+md5.new(r%%r).hexdigest()';import md5;print "MD5 sum of my source is: "+md5.new(r%r).hexdigest()

Saída:

MD5 sum of my source is: bb74dfc895c13ab991c4336e75865426

Verificação em ideone

Matt
fonte
Estou recebendo um md5sum diferente para o arquivo de origem.
Skeevey
@slackwear o que você está recebendo?
Matt
oh, você editou novamente. Agora eu fico 24ba0a79636297dab8803f571d4e3b44 md.pyusando md5sum em Linux
skeevey
1
@slackwear se eu adicionar uma nova linha ( \n) no final do meu programa eu recebo o hash você postou: 24ba0a79636297dab8803f571d4e3b44. Estou bastante certo de que você tem uma nova linha extra. (Eu acredito que alguns editores irá fazer isso automaticamente)
Matt
2
Você está certo. Eu estava vim desconhecem iria esconder arrastando LFs
skeevey
12

Python 2, 91 bytes

s="import md5;print'MD5 sum of my source is: '+md5.new('s=%r;exec s'%s).hexdigest()";exec s

Usando a variante quine Python, que não requer repetir tudo duas vezes. Testado em ideone .

Sp3000
fonte
1
esta deve ser a resposta aceita
micsthepick
1

Perl + Digest :: MD5, 89 bytes

$_=q(use Digest::MD5 md5_hex;say"MD5 sum of my source is: ",md5_hex"\$_=q($_);eval");eval

Nenhum link TIO porque o Digest :: MD5 não está instalado no TIO. Observe que isso exige que o nível de conformidade do idioma seja definido como 5.10 ou superior ( -M5.010; isso não implica uma penalidade de bytes, de acordo com as regras do PPCG.

Explicação

Este é mais um desafio "imprimir uma função do código fonte", o que significa que ele pode ser resolvido trivialmente através de um construtor de quine universal.

Construtor de quine universal

$_=q(…"\$_=q($_);eval");eval

Usamos a q()notação de seqüência de caracteres (que aninha) para inicializar $_, a variável "padrão" que o Perl usa para argumentos ausentes. Em seguida, temos evalum argumento ausente, para que a string dentro do q()seja avaliada.

A string dentro de q()é uma descrição de como criar o programa inteiro; nós especificamos o restante do programa literalmente, depois usamos um sem escape $_para substituir a string inteira por dentro.

A técnica cria assim uma cadeia de caracteres com conteúdo idêntico à fonte do programa inteiro; nós poderíamos imprimi-lo para produzir uma solução. Também podemos fazer outras coisas primeiro, criando um construtor universal de quine.

O resto do programa

use Digest::MD5 md5_hex;say"MD5 sum of my source is: ",md5_hex

Muito simples: importe um MD5 embutido, imprima a string fixa especificada na pergunta (não vale a pena compactá-lo, acredito que no Perl o descompactador ocuparia mais espaço do que apenas declarar literalmente a string) e use o MD5 embutido a string que recebemos através do construtor universal de quine.


fonte
0

Node.js REPL (versão 0.9.3), 96 94 bytes

Usando a última versão do Node.js que existia quando este desafio foi lançado. Rastreei a documentação de 9 de novembro de 2012 para o módulo de criptografia do Node.js. e ele suportava todas as funções que usei aqui no passado.

function x(s){return require("crypto").createHash("md5").update(s+";x(x)").digest("hex")};x(x)

Se você não deseja instalar uma versão antiga do Node.js apenas para testar esse código, tenha certeza de que ele também funciona na versão mais recente.

Node.js REPL (versão 7.0.0), 81 bytes

E aqui está uma versão usando as funções de seta do ES6.

x=s=>require("crypto").createHash("md5").update(`x=${s};x(x)`).digest("hex");x(x)

Edit : obrigado a Anders Kaseorg por apontar um erro na minha versão do Node.js. 0.9.3, corrigindo o que salvou dois bytes.

user2428118
fonte
Embora todas as funções que você usou possam ter sido suportadas pelo Node.js. 0.9.3, a sintaxe literal do modelo ES6 `${s};x(x)`não era.
Anders Kaseorg
@AndersKaseorg Corrigido, obrigado. Acontece que não usar um literal de modelo na verdade salva alguns bytes na versão 0.9.3 do Node.js.
user2428118