Compiled quine variant
Assembly (DOS .com file)
start:
%rep 2
call $+3
mov ah, 9
mov dx, 100h + (end - start) / 2
int 21h
mov ah, 2
mov dl, "$" - 1
inc dx
int 21h
ret
db "$"
%endrep
end:
Assemble with nasm quine.asm -o quine.com
. Try with dosbox quine.com
.
Proof of correctness (you can also verify by the smilies here):
Python 2.7.3
#!/usr/bin/env python
import sys
import time
import struct
import compiledquine
_ = '\x63\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x40\x00\x00\x00\x73\x6e\x00\x00\x00\x64\x00\x00\x64\x01\x00\x6c\x00\x00\x5a\x00\x00\x64\x00\x00\x64\x01\x00\x6c\x01\x00\x5a\x01\x00\x64\x00\x00\x64\x01\x00\x6c\x02\x00\x5a\x02\x00\x64\x00\x00\x64\x01\x00\x6c\x03\x00\x5a\x03\x00\x64\x02\x00\x5a\x04\x00\x65\x00\x00\x6a\x05\x00\x6a\x06\x00\x64\x03\x00\x65\x02\x00\x6a\x07\x00\x64\x04\x00\x65\x08\x00\x65\x01\x00\x6a\x01\x00\x83\x00\x00\x83\x01\x00\x83\x02\x00\x17\x65\x04\x00\x65\x04\x00\x16\x17\x83\x01\x00\x01\x64\x01\x00\x53\x28\x05\x00\x00\x00\x69\xff\xff\xff\xff\x4e\x73\x08\x00\x00\x00%s\x73\x04\x00\x00\x00\x03\xf3\x0d\x0a\x74\x01\x00\x00\x00\x49\x28\x09\x00\x00\x00\x74\x03\x00\x00\x00\x73\x79\x73\x74\x04\x00\x00\x00\x74\x69\x6d\x65\x74\x06\x00\x00\x00\x73\x74\x72\x75\x63\x74\x74\x0d\x00\x00\x00\x63\x6f\x6d\x70\x69\x6c\x65\x64\x71\x75\x69\x6e\x65\x74\x01\x00\x00\x00\x5f\x74\x06\x00\x00\x00\x73\x74\x64\x6f\x75\x74\x74\x05\x00\x00\x00\x77\x72\x69\x74\x65\x74\x04\x00\x00\x00\x70\x61\x63\x6b\x74\x03\x00\x00\x00\x69\x6e\x74\x28\x00\x00\x00\x00\x28\x00\x00\x00\x00\x28\x00\x00\x00\x00\x73\x1c\x00\x00\x00\x2f\x68\x6f\x6d\x65\x2f\x67\x72\x61\x6e\x74\x2f\x63\x6f\x6d\x70\x69\x6c\x65\x64\x71\x75\x69\x6e\x65\x2e\x70\x79\x74\x08\x00\x00\x00\x3c\x6d\x6f\x64\x75\x6c\x65\x3e\x02\x00\x00\x00\x73\x0a\x00\x00\x00\x0c\x01\x0c\x01\x0c\x01\x0c\x02\x06\x01'
sys.stdout.write('\x03\xf3\x0d\x0a' + struct.pack('I', int(time.time())) + _ % _)
Note that this must be saved as compiledquine.py
. These are the results I get:
$ ./compiledquine.py > compiledquine.py.out
$ md5sum compiledquine.pyc compiledquine.py.out
4b82e7d94d0d59e3d647d775fffc1948 compiledquine.pyc
4b82e7d94d0d59e3d647d775fffc1948 compiledquine.py.out
I won't guarantee that it'll work for you, but it does consistently work for me. Here's what happens:
- At the bottom of the import statements, the script itself is imported. This compiles it to a .pyc file.
- The variable
_
is filled with the program's bytecode starting at byte 0x08, except%s
is put in place of the variable itself. - The script fills in the first 4 'magic' bytes, which are specific to Python 2.7.3, followed by the timestamp in the next 4 bytes, which is generated by
struct.pack
andtime.time
, and then adds_ % _
to complete the output. (That last bit is borrowed from some other Python quines.) - Because of the timestamp at the beginning, this script technically isn't always accurate. If the self-import and the last line execute in different seconds, the output will be a byte off.