22
\$\begingroup\$

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.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ If 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. \$\endgroup\$
    – Nick T
    Dec 19, 2013 at 9:40
  • 1
    \$\begingroup\$ @NickT That would be extremely difficult though, I might add. \$\endgroup\$ Jul 12, 2015 at 2:28

4 Answers 4

14
\$\begingroup\$

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.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ this should be the accepted answer \$\endgroup\$ Jun 7, 2018 at 0:34
13
+50
\$\begingroup\$

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

\$\endgroup\$
10
  • \$\begingroup\$ I'm getting a different md5sum for the source file. \$\endgroup\$
    – skeevey
    Nov 9, 2012 at 13:38
  • \$\begingroup\$ @slackwear what are you getting? \$\endgroup\$
    – Matt
    Nov 9, 2012 at 13:39
  • \$\begingroup\$ oh you've edited it again. Right now I get 24ba0a79636297dab8803f571d4e3b44 md.py using md5sum in linux \$\endgroup\$
    – skeevey
    Nov 9, 2012 at 13:43
  • 1
    \$\begingroup\$ @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) \$\endgroup\$
    – Matt
    Nov 9, 2012 at 13:51
  • 2
    \$\begingroup\$ You are correct. I was unaware vim would hide trailing LFs \$\endgroup\$
    – skeevey
    Nov 9, 2012 at 13:54
3
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$ Jun 11, 2017 at 9:43
  • \$\begingroup\$ @AndersKaseorg Fixed, thanks. Turns out not using a template literal actually saves some bytes in the Node.js 0.9.3 version. \$\endgroup\$ Jun 21, 2017 at 15:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.