可以“繁殖”的程序

Python描述

编写这样一个py脚本文件:

  • 每次运行这个脚本文件,在工作目录下以随机文件名创建一个新文件,文件内容为这个py脚本自身。
  • 不能使用sys.argv[0],即不能借助操作系统的帮助。

一种解答:

m = r"""from random import sample
chrs = [chr(i) for i in range(ord("A"), ord("Z") + 1)]
with open("".join(sample(chrs, 5)) + ".py", "w") as f:
    print("m=r\"\"\"{}\"\"\"".format(m), file=f)
    print(m, file=f)
"""
from random import sample
chrs = [chr(i) for i in range(ord("A"), ord("Z") + 1)]
with open("".join(sample(chrs, 5)) + ".py", "w") as f:
    print("m=r\"\"\"{}\"\"\"".format(m), file=f)
    print(m, file=f)

C语言描述

如果语言不提供原始字符串功能呢?

编写一个.c文件并编译成.exe程序,要求该程序能实现如下效果:
运行该.exe文件,在标准输出流中打印自己的源代码(即.c文件内容)

一种解答:

#include <stdio.h>

const char* m =
  "\";\n\nvoid\nprint_raw_str(const char* s)\n{\n  char c = *s;\n  while (c != "
  "'\\0') {\n    switch (c) {\n      case '\\\\':\n        "
  "printf(\"\\\\\\\\\");\n        break;\n      case '\\\"':\n        "
  "printf(\"\\\\\\\"\");\n        break;\n      case '\\n':\n        "
  "printf(\"\\\\n\");\n        break;\n      default:\n        printf(\"%c\", "
  "c);\n    }\n    c = *++s;\n  }\n}\n\nint\nmain()\n{\n  printf(\"%s\", "
  "\"#include <stdio.h>\\n\\nconst char* m = \\\"\");\n  print_raw_str(m);\n  "
  "printf(\"%s\", m);\n}\n";

void
print_raw_str(const char* s)
{
  char c = *s;
  while (c != '\0') {
    switch (c) {
      case '\\':
        printf("\\\\");
        break;
      case '\"':
        printf("\\\"");
        break;
      case '\n':
        printf("\\n");
        break;
      default:
        printf("%c", c);
    }
    c = *++s;
  }
}

int
main()
{
  printf("%s", "#include <stdio.h>\n\nconst char* m = \"");
  print_raw_str(m);
  printf("%s", m);
}

亚当和夏娃

上两节给出的代码就像他们“代码族”的亚当和夏娃,它们都可以实现“鸡生蛋,蛋生鸡”的怪诞循环,对于py脚本,则可以直接实现“无性生殖”。

严格来说,上面两节给出的代码并非完全符合要求的代码。

这样做即可得到真正符合要求的代码(以C语言形式为例):

  1. 使用编译器编译上面给出的代码:
    $gcc a.c
    
    得到a.exe文件
  2. 运行a.exe文件,其输出才是完全符合要求的源代码:
    $a.exe > b.c
    
    得到b.c文件,b.c文件才是真正符合要求的代码。

如何写出可以“繁殖”的程序

可以给繁殖过程加入各种复杂功能,比如:“一次生俩”,下面是教程。

以Python为例,只需两步:

  1. 写出如下代码框架
    m = r""""""
    # 插入其它代码
    print("m=r\"\"\"{}\"\"\"".format(m))
    print(m)
    # 插入其它代码
    
    两行print是核心、关键。
  2. 把第二行到最后一行复杂粘贴到m中
    m = r"""# 插入其它代码
    print("m=r\"\"\"{}\"\"\"".format(m))
    print(m)
    # 插入其它代码
    """
    # 插入其它代码
    print("m=r\"\"\"{}\"\"\"".format(m))
    print(m)
    # 插入其它代码
    
  3. 大功告成,这个程序就可以在stdout中打印自己的源代码了。

由于C语言没有原始字符串的机制,所以要自己插入一个“反转义”的函数。

意义

什么程序会要做这种奇怪的事情呢?

答案是“计算机病毒”,或者“人工智能”。

有些人会说,借助操作系统提供的argv[0]不就行了吗,搞那么复杂干嘛?

那么问题来了:“没有操作系统就没有计算机病毒吗?计算机病毒必须依靠操作系统才能存活吗?

答案是否定的,按这种方式,裸机+汇编编程都能写出可自我繁殖的程序。

附注

考察生命科学相关的一个悖论:

  1. 生物都是机器
  2. 生物都能自再生(繁殖)
  3. 机器不能自再生

关于第三句话:
例如汽车和生产汽车的自动生产线,设计生产线比设计汽车更加复杂,因为生产线中包含了汽车的设计。
因为任何生产机器B的机器A,A肯定比B更复杂。一个机器不会比他自己更复杂,所以没有机器能制造它自己,故机器不能自再生。

答案是:这个悖论是不成立的,机器可以自再生

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值