Cryptographic quine variant

22

2

Create a program that prints the MD5 sum of its source in the form:

MD5 sum of my source is: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

No cheating - you can't just read the source file and compute its sum. The program must not read any external information.

Of course you can use a MD5 library available for your language.

Petr Pudlák

Posted 2012-11-09T12:08:52.913

Reputation: 4 272

1@NickT That would be extremely difficult though, I might add. – PyRulez – 2015-07-12T02:28:25.790

1If someone manages to collide MD5 (i.e. h = f(h), where f is a crude "salt" for h with all the code garbage that is needed to print), I think they should be allowed to do that. – Nick T – 2013-12-19T09:40:23.273

Answers

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()

Output:

MD5 sum of my source is: bb74dfc895c13ab991c4336e75865426

Verification at ideone

Matt

Posted 2012-11-09T12:08:52.913

Reputation: 1 395

I'm getting a different md5sum for the source file. – skeevey – 2012-11-09T13:38:59.323

@slackwear what are you getting? – Matt – 2012-11-09T13:39:54.157

oh you've edited it again. Right now I get 24ba0a79636297dab8803f571d4e3b44 md.py using md5sum in linux – skeevey – 2012-11-09T13:43:22.137

@slackwear it looks like you have an extra newline at the end of your source file – Matt – 2012-11-09T13:48:56.107

I've tried it with and without a trailing newline...maybe i'm missing something here – skeevey – 2012-11-09T13:50:09.150

1@slackwear if I add a newline (\n) at the end of my program I get the hash you posted: 24ba0a79636297dab8803f571d4e3b44. I'm fairly certain that you have an extra newline. (I believe some editors will do this automatically) – Matt – 2012-11-09T13:51:39.630

2You are correct. I was unaware vim would hide trailing LFs – skeevey – 2012-11-09T13:54:47.380

I confirm that the program performs as claimed: http://ideone.com/oYJvQh

– r.e.s. – 2012-11-09T13:58:44.263

hm, what it should do ? why not just print md5 sum of some fixed random string ? – zb' – 2016-11-07T06:04:13.317

@zb' The problem asks to print the MD5 sum of the source code, not just any string. – HyperNeutrino – 2017-06-11T20:57:02.163

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

Using the Python quine variant which doesn't require repeating everything twice. Tested on ideone.

Sp3000

Posted 2012-11-09T12:08:52.913

Reputation: 58 729

1this should be the accepted answer – micsthepick – 2018-06-07T00:34:23.640

1

Perl + Digest::MD5, 89 bytes

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

No TIO link because Digest::MD5 is not installed on TIO. Note that this requires the language conformance level to be set to 5.10 or higher (-M5.010; this doesn't carry a byte penalty according to PPCG rules.

Explanation

This is yet another "print a function of the source code" challenge, meaning that it can be trivially solved via a universal quine constructor.

Universal quine constructor

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

We use the q() string notation (which nests) to initialize $_, the "default" variable that Perl uses for missing arguments. Then we eval with a missing argument, so that the string inside the q() gets evaluated.

The string inside the q() is a description of how to create the entire program; we specify the rest of the program literally, then use an unescaped $_ to substitute the whole string in for the inside.

The technique thus creates a string with identical contents to the entire program's source; we could print it to produce a quine. We can also do other things to it first, though, making a universal quine constructor.

The rest of the program

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

Very simple: import an MD5 builtin, then print the fixed string specified in the question (it's not worth compressing it, I believe that in Perl the decompressor would take up more space than just stating the string literally), and use the MD5 builtin on the string we got via the universal quine constructor.

user62131

Posted 2012-11-09T12:08:52.913

Reputation:

0

Node.js REPL (version 0.9.3), 96 94 bytes

Using the last version of Node.js that existed when this challenge was posted. I've tracked down the November 9, 2012 documentation for Node.js' crypto module, and it did support all the functions I've used here back in the day.

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

If you don't feel like installing an antique version of Node.js just to test this code, rest assured it also works in the most recent version.

Node.js REPL (version 7.0.0), 81 bytes

And here is a version using ES6's arrow functions.

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

Edit: thanks to Anders Kaseorg for pointing out an error in my Node.js 0.9.3 version, fixing which saved two bytes.

user2428118

Posted 2012-11-09T12:08:52.913

Reputation: 2 000

Although all the functions you used may have been supported by Node.js 0.9.3, the ES6 template literal syntax \${s};x(x)`` was not. – Anders Kaseorg – 2017-06-11T09:43:50.337

@AndersKaseorg Fixed, thanks. Turns out not using a template literal actually saves some bytes in the Node.js 0.9.3 version. – user2428118 – 2017-06-21T15:40:17.950