自己複製プログラムを作成します。


11

実行時に自分自身をコピーする簡単なプログラムを作成します。

プログラムは、Windows、Linuxなどの何らかの実行可能ファイルである必要があり、元の実行可能ファイルと同じ新しい実行可能ファイルをランダムな名前で生成し、終了する必要があります。

あなたのプログラム、いかなる種類のファイルの読み取りやコピーも含むべきではありません。新しい実行可能ファイルを生成するためのファイル書き込みのみが許可されます。

(PS。ウィキペディアで記事にSelf-replicating programリダイレクトするとき、私はかなり恥ずかしかったComputer virus...:/ ...)

最小の実行可能ファイルサイズが優先されます。あなたの答えは、適切なOSとコンパイラを備えたプログラミングコード、アセンブリコード、または実行可能ファイルのHEXダンプです。


6
これは、既存の[クイン]チャレンジとわずかに異なるようです。または私は誤解しましたか?
dmckee ---元モデレーター子猫

1
@dmckee アセンブリ言語クイン自己複製Hello Worldプログラムがコピーを受け入れているのを見ましたが、プログラムがコードではなく自分自身を書くのを見つけることができませんでした。
JiminP

1
...しかし、実際にどのように機能するかを知りたい!.. WikipediaでQuineの記事を読んでも、バイナリコードでアイデアをどのように拡張できるかわかりません。PS。複製用のコンパイラおよびスクリプト言語は許可されていません...:/
JiminP

4
より多くの制約を追加することで、問題をわずかに難しくandくすることができます。この問題は、クイン問題の些細な拡張だと思います。
アレクサンドル

1
実行可能ファイルの最小サイズが勝った場合、コンパイル済み言語のユーザーにとって公平になるように、実行可能ファイルのサイズの一部としてインタープリターコードも考慮すべきではありませんか?
トーマスディグナン

回答:


4

バッシュ、236

厳密に必要以上に長いですが、私は長い列が嫌いです。末尾の改行はオプションではありません。

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

実際に、それは私が「間違った」という質問を書いてから、私は、しかし、望んでいないですし、あなたの答えは...素晴らしいQUINEある
JiminP

@JiminP:どうして望んでいないのですか?問題の説明をもう一度2度読んだだけで、理解できません。
JB

まあ...私が欲しかったのは実行可能なバイナリコードでした。私が上で認めたように、私の質問はまったく「正しい」ものではなかったので...ごめんなさい。
JiminP

3
@JiminPええ、ええ、質問には「バイナリ」という単語はまったく表示されません。私はコメントでそれを見つけましたが、そのような制限のために、それはちょうどそれをカットしません。コメントからのすべての統合された入力を使用して、新しい質問を開くことができます。レギュラーが小さな詳細を解決するのを確実にするために、サンドボックスを使用することをお勧めします。しかし、注意してください、バイナリの回答は退屈な傾向があります。
JB

10

x86 Linuxのアセンブリ、106バイト

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

これは、nasmアセンブラ用です。コマンドラインでバイナリをビルドします。nasm -f bin -o a.out selfrep.asm && chmod +x a.out

16進ダンプと同じファイルを次に示します。 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

要求に応じて、プログラムは自分自身を別のファイルにコピーします。(プログラムは、stdoutに書き込み、ユーザーにファイルへのリダイレクトを許可した場合、大幅に短くなる可能性があります。)

サイズを小さくするために境界線のトリックを使用することは避けました。これは完全に準拠した32ビットELFバイナリである必要があります。

追加して編集:上記のバージョンでは、作成されたファイルは単なるファイルですが、数バイト(およびルールの小さな曲がり)で、もう少し面白いものを作成できることがわかりました。このバージョンは2バイトだけ長く、108バイトです。

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

asr「自己複製器」のこのバージョンに名前を付けます。nasm -f bin -o asr asr.asm && chmod +x asr

nasm障害のある16進ダンプバージョン: 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

実行すると、という名前のほぼ同一のファイルが作成されますがbsr、それ自体は実行可能です。これを実行すると、という名前の別のバイナリファイルが作成されcsrます。等々。

(その後、迷惑なことが起こり始めることに注意してくださいzsr。名前の変更をカスケードするバージョンを作成することを検討しましたatrが、それまではほとんどの人が退屈するだろうと思うので、おそらく余分なバイトすべての価値はありません。 )


アセンブリの回答については+1!あなたはアセンブリクインの挑戦を見ましたか?
MD XF

2

以下は、.NETのコンパイルサービスを使用してソースコードをオンザフライでコンパイルし、同一の出力を生成する方法を示す概念実証(変更なし)です。最初のコピーは元のコピーと同一ではありませんが、後続の実行からの後続のコピーはランダムなファイル名とまったく同じです。

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);
        }
    }
}

コマンドラインでのデモ出力:

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>

2

バッチ

バージョン1(30バイト)

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

私の勝ち!:)


%0参照により、ファイルからの読み取りが発生し、ルールに違反します。また、私のバイナリバージョンはさらに短くなっています。:-)
ピーターフェリー

1

DOS COMファイル-50バイト

ファイルを作成し、現在の時刻のものを数字に置き換えられています。COMフ​​ァイルは、データセグメントのオフセットでメモリにロードされるだけなので(CSとDSは同じに設定されます)、このメモリをファイルに書き込むだけです。X.COMX100h

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ソース

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

1

DOS .COMファイル、29バイト

「@」は、アルファベットの前半部分の奇数文字(A、C、E、Gなど)にランダムに置き換えられます。出力ファイルは、255バイトまたは256バイトです。(デバッガではなく)実際のDOSの初期レジスタは、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

0

DOS COMファイル-36バイト

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 

出力ファイル名はコマンドラインで指定され、8.3形式に切り捨てられ、スペースはOKです(DOSファイル名のスペースは有効です)。WinXPコマンドプロンプトを使用してテストしました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.