# Write a self-replicating program.

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.

• This seems to vary only trivially from the existing [quine] challenges. Or have I misunderstood? – dmckee --- ex-moderator kitten Jun 22 '11 at 6:06
• @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 Jun 22 '11 at 6:19
• ... 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 Jun 22 '11 at 6:26
• Any 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 Jun 22 '11 at 10:22
• If 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 Dec 18 '11 at 19:16

## 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=bb q=bq r=br d=bd; echo s=qsq' t='echo t=qtq; echo s; echo t; chmod 777$$' exec >$$; echo b=bb q=bq r=br d=bd; echo s=qsq echo t=qtq; echo s; echo t; chmod 777$$  • Actually, it's not what I wanted, however, since I wrote a "wrong" question and your answer is a great quine... – JiminP Sep 27 '11 at 6:29 • @JiminP: How is it not what you wanted? I just read the problem description twice again, and fail to understand. – J B Sep 27 '11 at 20:54 • Well... what I wanted was an executable binary code. As I admitted above, since my question was not quite 'right'... sorry for that. – JiminP Sep 28 '11 at 0:16 • @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 Sep 28 '11 at 4:37 ## 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
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.) 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>  # Batch ## Version 1 (30 bytes) type%0>%random%.bat&type%0>con  I win! :) • the %0 reference causes a read from the file, which violates the rules. Besides, my binary version is even shorter. :-) – peter ferrie Nov 26 '17 at 5:38 ## 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-


## 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

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.