Write a self-replicating program.

11

2

Write a simple program that copies itself when executed.

Your program should be some kind of executable file on Windows, Linux, etc.., should generate new executable file, which is identical to your original executable file, with random name, and quits.

Your program shouldn't involve any kind of file reading or copying. Only file writing for generating new executable file is permitted.

(PS. I was quite embarrassed when at Wikipedia, Self-replicating program redirects to Computer virus article... :/...)

Smallest executable file size wins. Your answer may be a programming code with proper OS & compiler, assembly code, or HEX dump of a executable file.

JiminP

Posted 2011-06-22T04:50:46.843

Reputation: 3 264

6This seems to vary only trivially from the existing [quine] challenges. Or have I misunderstood? – dmckee --- ex-moderator kitten – 2011-06-22T06:06:12.327

1

@dmckee I saw Assembly Language Quine and Self replicating Hello World program accepting copying, but I couldn't find program writes itself, not its code.

– JiminP – 2011-06-22T06:19:43.040

For scripting languages (like say the three top answers to Golf you a quine for great good! ) there is no distinction between code and program, and the basic technique for building quines extends exactly to embedding compiled binaries instead of the source code.

– dmckee --- ex-moderator kitten – 2011-06-22T06:23:38.910

1... but I want to see how it actually works!.. I don't know how the idea can be extended with binary codes.. even though I read Quine article at Wikipedia. PS. no compilers for replicating and no script languages are allowed... :/ – JiminP – 2011-06-22T06:26:04.883

Alright, I have some ideas, but I don't think that this problem isn't quite as easy as quine.. – JiminP – 2011-06-22T06:36:26.873

4Any problem can be made slightly harder and uglier by adding more constraints to it. I find this problem a trivial extension of the quine problem. – Alexandru – 2011-06-22T10:22:40.740

I edited your question. Scripts are executables (even .bat, .wsh and .js-Files are executable on Windows). You meant compiled files, native executable, binary files, which are, indeed, a different beast. Maybe you don't like JVM-bytecode? Then feel free to reedit. – user unknown – 2011-06-22T13:48:11.513

This question should not make @JiminP quite embarrassed as stays on the speech "Reflections on Trusting Trust" by Ken Thompson as a good practice.

– H_7 – 2011-10-01T14:45:30.947

1If smallest executable size wins, shouldn't we also factor in the interpreter code as part of the executable size for this to be fair to users of compiled languages? – Thomas Dignan – 2011-12-18T19:16:04.790

Answers

4

Bash, 236

Longer than strictly necessary, but I hate long lines. The trailing newline is non-optional.

b=\\ q=\' r=\> d=\$
s='exec >$$; echo b=$b$b q=$b$q r=$b$r d=$b$d; echo s=$q$s$q'
t='echo t=$q$t$q; echo $s; echo $t; chmod 777 $$'
exec >$$; echo b=$b$b q=$b$q r=$b$r d=$b$d; echo s=$q$s$q
echo t=$q$t$q; echo $s; echo $t; chmod 777 $$

J B

Posted 2011-06-22T04:50:46.843

Reputation: 9 638

Actually, it's not what I wanted, however, since I wrote a "wrong" question and your answer is a great quine... – JiminP – 2011-09-27T06:29:43.683

@JiminP: How is it not what you wanted? I just read the problem description twice again, and fail to understand. – J B – 2011-09-27T20:54:22.617

Well... what I wanted was an executable binary code. As I admitted above, since my question was not quite 'right'... sorry for that. – JiminP – 2011-09-28T00:16:06.337

3

@JiminP Well, yeah, the word "binary" doesn't appear at all in the question. I just found it in the comments, but for such a restriction, it just doesn't cut it. You could open a new question with all the consolidated input from the comments. I suggest you used the sandbox to ensure the regulars help you iron out the little details. But beware, binary answers tend to be real boring.

– J B – 2011-09-28T04:37:03.863

10

Assembly for x86 Linux, 106 bytes

BITS 32
                org     0x2E620000
                db      0x7F, "ELF", 1, 1, 1, 0 ; e_ident
                dd      0, 0
                dw      2                       ; e_type
                dw      3                       ; e_machine
                dd      1                       ; e_version
                dd      _start                  ; e_entry
                dd      phdr - $$               ; e_phoff
                dd      0                       ; e_shoff
                dd      0                       ; e_flags
                dw      0x34                    ; e_ehsize
                dw      0x20                    ; e_phentsize
phdr:           dd      1                       ; e_phnum       ; p_type
                                                ; e_shentsize
                dd      0                       ; e_shnum       ; p_offset
                                                ; e_shstrndx
                dd      $$                                      ; p_vaddr
fname           equ     $ - 2
                db      'out', 0                                ; p_paddr
                dd      filesize                                ; p_filesz
                dd      filesize                                ; p_memsz
                dd      5                                       ; p_flags
                dd      0x1000                                  ; p_align
_start:         mov     al, 5                   ; 5 = open syscall
                mov     ebx, fname
                mov     cl, 65                  ; 65 = O_WRONLY | O_CREAT
                mov     dx, 666q
                int     0x80
                lea     edx, [byte ecx + filesize - 65]
                xchg    eax, ebx
                xchg    eax, ecx
                mov     cl, 0
                mov     al, 4                   ; 4 = write syscall
                int     0x80
                mov     al, 1                   ; 1 = exit syscall
                int     0x80
filesize        equ     $ - $$

This is for the nasm assembler. Build the binary with the command line: nasm -f bin -o a.out selfrep.asm && chmod +x a.out

Here's the same file as a hex dump: 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 4C 00 62 2E 2C 00 00 00 00 00 00 00 00 00 00 00 34 00 20 00 01 00 00 00 00 00 00 00 00 00 62 2E 6F 75 74 00 6A 00 00 00 6A 00 00 00 05 00 00 00 00 10 00 00 B0 05 BB 36 00 62 2E B1 41 66 BA B6 01 CD 80 8D 51 29 93 91 B1 00 B0 04 CD 80 B0 01 CD 80

As requested, the program copies itself to a separate file. (The program could have been significantly shorter if it had been allowed to just write to stdout and let the user redirect to a file.)

I avoided using any borderline tricks to reduce the size. This should be a fully conformant 32-bit ELF binary.

Edited to add: In the above version the created file is just a plain file, but it occurs to me that for a couple of bytes (and a tiny bend of the rules), you can create something a little more interesting. This version is only two bytes longer, at 108 bytes:

BITS 32
                org     0x00010000
                db      0x7F, "ELF", 1, 1, 1, 0 ; e_ident
                dd      0, 0
                dw      2                       ; e_type
                dw      3                       ; e_machine
                dd      1                       ; e_version
                dd      _start                  ; e_entry
                dd      phdr - $$               ; e_phoff
                dd      0                       ; e_shoff
                dd      0                       ; e_flags
                dw      0x34                    ; e_ehsize
                dw      0x20                    ; e_phentsize
phdr:           dd      1                       ; e_phnum       ; p_type
                                                ; e_shentsize
                dd      0                       ; e_shnum       ; p_offset
                                                ; e_shstrndx
                dd      $$                                      ; p_vaddr
fname:          db      'asr', 0                                ; p_paddr
                dd      filesize                                ; p_filesz
                dd      filesize                                ; p_memsz
                dd      7                                       ; p_flags
                dd      0x1000                                  ; p_align
_start:         mov     al, 5                   ; 5 = open syscall
                mov     ebx, fname
                inc     byte [ebx]
                mov     cl, 65                  ; 65 = O_WRONLY | O_CREAT
                mov     dx, 777q
                int     0x80
                lea     edx, [byte ecx + filesize - 65]
                xchg    eax, ebx
                xchg    eax, ecx
                mov     cl, 0
                mov     al, 4                   ; 4 = write syscall
                int     0x80
                mov     al, 1                   ; 1 = exit syscall
                int     0x80
filesize        equ     $ - $$

Name this version asr, for "a self-replicator": nasm -f bin -o asr asr.asm && chmod +x asr

Hex dump version for the nasm-impaired: 7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 4C 00 01 00 2C 00 00 00 00 00 00 00 00 00 00 00 34 00 20 00 01 00 00 00 00 00 00 00 00 00 01 00 61 73 72 00 6C 00 00 00 6C 00 00 00 07 00 00 00 00 10 00 00 B0 05 BB 38 00 01 00 FE 03 B1 41 66 BA FF 01 CD 80 8D 51 2B 93 91 B1 00 B0 04 CD 80 B0 01 CD 80

When you run it, it creates an almost-identical file named bsr, but one that is itself executable. Running it will create another binary file named csr. And so on.

(Note that annoying things start to happen after zsr. I considered making a version that would cascade the name change to atr and so on, but I think most people will get bored well before then, so it probably isn't worth all the extra bytes.)

breadbox

Posted 2011-06-22T04:50:46.843

Reputation: 6 893

+1 for assembly answer! Have you seen the assembly quine challenge?

– MD XF – 2017-05-25T01:48:56.833

2

Here is a proof-of-concept (ungolfed) that shows how the Compilation services in .NET might be used to compile the source code on-the-fly to generate an identical output. The first copy is not identical to the original, but subsequent copies from subsequent runs are exactly identical with random file names:

using System;
using Microsoft.CSharp;
using System.CodeDom.Compiler;

namespace _2947
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello world!");

            var s = @"
using System;
using System.CodeDom.Compiler;
using Microsoft.CSharp;

namespace _2947
{{
    class Program
    {{
        static void Main(string[] args)
        {{
            Console.WriteLine({1}Hello world!{1});

            var s = @{1}{0}{1};
            s = string.Format(s, s, '{1}');

            string exeName = Environment.CurrentDirectory + @{1}\{1} + new Random().Next(1000, 9999) + {1}.exe{1};

            CompilerParameters cp = new CompilerParameters();
            cp.GenerateExecutable = true;
            cp.OutputAssembly = exeName;
            cp.GenerateInMemory = false;
            cp.TreatWarningsAsErrors = false;
            cp.ReferencedAssemblies.Add({1}System.dll{1});

            var c = CSharpCodeProvider.CreateProvider({1}cs{1});
            var cr = c.CompileAssemblyFromSource(cp, s);
        }}
    }}
}}
";
            s = string.Format(s, s, '"');

            string exeName = Environment.CurrentDirectory + @"\" + new Random().Next(1000, 9999) + ".exe";

            CompilerParameters cp = new CompilerParameters();
            cp.GenerateExecutable = true;
            cp.OutputAssembly = exeName;
            cp.GenerateInMemory = false;
            cp.TreatWarningsAsErrors = false;
            cp.ReferencedAssemblies.Add("System.dll");

            var c = CSharpCodeProvider.CreateProvider("cs");
            var cr = c.CompileAssemblyFromSource(cp, s);
        }
    }
}

Demonstration output on command-line:

C:\projects\codegolf\2947\2947\bin\Debug>2947
Hello world!

C:\projects\codegolf\2947\2947\bin\Debug>dir
 Volume in drive C has no label.
 Volume Serial Number is 361D-4479

 Directory of C:\projects\codegolf\2947\2947\bin\Debug

09/27/2011  02:17 PM    <DIR>          .
09/27/2011  02:17 PM    <DIR>          ..
09/27/2011  02:17 PM             7,680 2947.exe
09/27/2011  02:17 PM            13,824 2947.pdb
09/27/2011  01:33 PM            11,600 2947.vshost.exe
09/27/2011  02:17 PM             6,656 8425.exe
               4 File(s)         39,760 bytes
               2 Dir(s)   6,486,368,256 bytes free

C:\projects\codegolf\2947\2947\bin\Debug>8425
Hello world!

C:\projects\codegolf\2947\2947\bin\Debug>dir
 Volume in drive C has no label.
 Volume Serial Number is 361D-4479

 Directory of C:\projects\codegolf\2947\2947\bin\Debug

09/27/2011  02:17 PM    <DIR>          .
09/27/2011  02:17 PM    <DIR>          ..
09/27/2011  02:17 PM             7,680 2947.exe
09/27/2011  02:17 PM            13,824 2947.pdb
09/27/2011  01:33 PM            11,600 2947.vshost.exe
09/27/2011  02:17 PM             6,656 7538.exe
09/27/2011  02:17 PM             6,656 8425.exe
               5 File(s)         46,416 bytes
               2 Dir(s)   6,486,360,064 bytes free

C:\projects\codegolf\2947\2947\bin\Debug>7538
Hello world!

C:\projects\codegolf\2947\2947\bin\Debug>dir
 Volume in drive C has no label.
 Volume Serial Number is 361D-4479

 Directory of C:\projects\codegolf\2947\2947\bin\Debug

09/27/2011  02:17 PM    <DIR>          .
09/27/2011  02:17 PM    <DIR>          ..
09/27/2011  02:17 PM             7,680 2947.exe
09/27/2011  02:17 PM            13,824 2947.pdb
09/27/2011  01:33 PM            11,600 2947.vshost.exe
09/27/2011  02:17 PM             6,656 4127.exe
09/27/2011  02:17 PM             6,656 7538.exe
09/27/2011  02:17 PM             6,656 8425.exe
               6 File(s)         53,072 bytes
               2 Dir(s)   6,486,351,872 bytes free

C:\projects\codegolf\2947\2947\bin\Debug>

mellamokb

Posted 2011-06-22T04:50:46.843

Reputation: 5 544

2

Batch

Version 1 (30 bytes)

type%0>%random%.bat&type%0>con

I win! :)

st0le

Posted 2011-06-22T04:50:46.843

Reputation: 2 002

the %0 reference causes a read from the file, which violates the rules. Besides, my binary version is even shorter. :-) – peter ferrie – 2017-11-26T05:38:34.947

1

DOS COM file - 50 bytes

Creates a file X.COM where X is replaced with the ones digit of the current time. COM files are simply loaded into memory at offset 100h of the data segment (CS and DS are set to be the same) so we can simply write this memory out to a file.

0000000: b402 cd1a 80e6 0f80 ce30 8836 2c01 31c9  .........0.6,.1.
0000010: ba2c 01b4 3ccd 21c6 062c 0178 89c3 b440  .,..<.!..,.x...@
0000020: ba00 01b9 3200 cd21 b44c cd21 782e 636f  ....2..!.L.!x.co
0000030: 6d00                                     m.

nasm source

org 100h ; this is a COM file
mov ah,02h ; fn=get time
int 1ah ; rtc interrupt
; convert to ascii - dh gets ones digit of seconds
and dh,0fh
or dh,30h
mov [fname],dh ; move time into filename
xor cx,cx ; clear attributes
mov dx,fname ; load filename
mov ah,3ch ; fn=create file
int 21h ; dos interrupt
mov byte [fname],'x' ; reset filename
mov bx,ax ; set filehandle
mov ah,40h ; fn=write to file
mov dx,100h ; offset is the loaded binary
mov cx,len ; length of write
int 21h ; dos iterrupt
mov ah,4ch ; fn=exit
int 21h ; dos interrupt
fname: db 'x.com',0
len equ $-$$

Geoff Reedy

Posted 2011-06-22T04:50:46.843

Reputation: 2 828

0

DOS .COM file, 29 bytes

The '@' is replaced randomly by an odd letter in the first half+ part of the alphabet (A, C, E, G, etc). Output files are either 255 or 256 bytes. Initial registers in real DOS (as opposed to a debugger) are that AX=0000, CX=00FF, SI=0100.

40       INC  AX         ;"@"
2E       CS:             ;"."
43       INC  BX         ;"C"
4F       DEC  DI         ;"O"
4D       DEC  BP         ;"M"
00 20    ADD  [BX+SI],AH ;"\0" and dummy parm
E4 40    IN   AL,40
24 0F    AND  AL,0F
0C 41    OR   AL,41
88 04    MOV  [SI],AL
B4 3C    MOV  AH,3C
41       INC  CX
89 F2    MOV  DX,SI
CD 21    INT  21
93       XCHG BX,AX
B4 40    MOV  AH,40
49       DEC  CX
CD 21    INT  21
C3       RET

peter ferrie

Posted 2011-06-22T04:50:46.843

Reputation: 804

0

DOS COM File - 36 bytes

56 BE 80 00 AD FE C8 A2 10 01 7E 17 89 F2 88 74
02 B4 3C 33 C9 CD 21 72 0A 8B D8 B4 40 5A B9 24
00 CD 21 C3 

Output file name is specified on the command line, truncated to 8.3 format, spaces OK (spaces in DOS filenames are legal). Tested using WinXP command prompt.

Skizz

Posted 2011-06-22T04:50:46.843

Reputation: 2 225