比尔盖子 博客

用Python3模拟《侏罗纪公园》中的黑客入侵情节

在《侏罗纪公园》中,有这样一段情节:一位黑客打开一个终端机,试图猜测管理员的密码。失败三次以后,终端上就出现死循环,不停输出:”You didn’t said the magic word!”。而更给力的是,在Youtube上,这段情节视频有一段留言,支持率很高:“The magic word is sudo!”。

而比尔盖子想到,最近刚刚开始学习Python3,是否可以写一段代码来模拟其中的情节?

逻辑设计:
给用户三次输入密码的机会,如果在这三次中用户输入错误,则让用户再次输入并显示错误信息。用户输入了sudo,则显示成功的信息。
如果用户连续三次密码输入错误,则进入死循环,不停显示“You didn’t said the magic word!”。

经过苦思冥想,比尔盖子写出这样一段代码:

#Copyright: Biergaizi | GPL V3
#Developer: Biergaizi, 2011
error = 0
#声明error这个变量,表示用户输入错误的次数

hack = input("Auth_Username:")
#提示用户输入验证用户名,并传入hack这个变量

once = 1
#声明once这个变量是1,表示这是第一次运行程序

while hack != ("sudo"):
#当用户输入的内容不等于sudo时,将程序置于一个循环中

 if once == 1:
  error = error + 1
  print("Permission denied!")
  once = 0
#如果用户是第一次运行程序,则将错误次数增加1,
#显示错误信息,并将once声明为0,表示这已不是第一次运行。并重新执行while块

#因为这是一个循环,因此当用户再次输入错误时,还会进入其中。但是once已经为0,
#因此程序会跳过上面的if块,执行下面的部分:
 hack = input("Auth_Username:")
 error = error + 1
 print("Permission denied")
#再次让用户输入,如果仍输入错误,则再次将错误次数增加1,显示错误信息。并重新执行while块

 if error == 3:
   while hack != ("sudo"):
    print("You didn't said the magic word!")
#如果错误次数以达到3次,则进入死循环,不停输出"You didn't said the magic word"

print("Dear Administrator, welcome!")
exit()
#这也许是这段程序中比较巧妙的部分,只要用户有一次输入"sudo",
#则会被跳出循环,显示这里的成功信息。

但这段代码逻辑还是有些混乱,而且之前的一个版本还存在一个Bug,不画流程图居然都看不出来。
因此,比尔盖子换一种思路:把验证用户名与增加错误次数的这段代码单独提出,写成一个函数,有点类似Linux里的PAM模块。

最终,比尔盖子想方设法精简代码,还是避免不了多了几行代码的事实:

#Copyright: Biergaizi | GPL V3
#Developer: Biergaizi, 2011
error=0
restart=1
#声明两个变量:restart和error,restart为1,error为0

def auth():
  global success,error
#将success,error声明为全局变量,使模块中对这两个变量可以赋值

  if hack == ("sudo"):
   success=1
  if hack != ("sudo"):
   success=0
   error=error+1
#这个模块很好理解,不解释

while restart==1:
#如果restart为1就进入循环,目的是故意构造死循环,
#重复判断,需要跳出死循环时可用break

 hack=input("Auth_Username:")
 auth()
#要求输入用户名,并调用auth模块判断

 if success==1:
  break
#如果用户输入了正确的内容,则用break跳出循环

 if error==3:
  while restart==1:
   print("You didn't said the magic word!")
#如果错误次数等于3,则restart为1进入循环,
#目的同样是构造死循环,并不停输出"You didn't said the magic word!"

 print("Permission denid!")
#这个print是写在这两个if判断之后的,也就是当用户既没有输入正确的内容,
#也没有累计错误三次(即第一、二次输入错误)时,显示错误信息并重复执行while块

print("Dear administrator, welcome!")
exit()
#在第28行,当用户输入正确的内容时,会break跳出循环,则会执行以下内容
#输出成功信息,并退出程序

最近,比尔盖子再次优化该程序:

error=0
import time

def auth(username):
  global error
  if username == ("sudo"):
   return 1
  if username != ("sudo"):
   error=error+1
   return 0

while True:
 hack=input("Auth_Username:")

 if auth(username=hack)==1:
  break
#如果用户输入了正确的内容,则用break跳出循环

 if error==3:
  while True:
   print("You didn't said the magic word!")
   time.sleep(0.5)
#如果错误次数等于3,则进入死循环,并不停输出"You didn't said the magic word!"

 print("Permission denid!")
#这个print是写在这两个if判断之后的,也就是当用户既没有输入正确的内容,
#也没有累计错误三次(即第一、二次输入错误)时,显示错误信息并重复执行while块

print("Dear administrator, welcome!")
exit()
#在第28行,当用户输入正确的内容时,会break跳出循环,则会执行以下内容
#输出成功信息,并退出程序

这样,一个用Python3模拟《侏罗纪公园》中的黑客入侵情节的程序就基本完成了,如果改进建议(比尔盖子最希望再精简代码)和批评意见(代码极不规范,但比尔盖子不知道怎样才规范),欢迎留言指出!

根据过路网友的建议,又修改了一下。在这段时间,比尔盖子的编程风格有了明显变化,第一是自加自减,第二是完全遵守了PEP8的标准,语法检查器没有任何形式的Warning。最不爽的就是那个全局变量了,回头想办法避免,其实很简单。

#!/usr/bin/python3
import time
error = 0

def auth(username):
    global error
    if username == ("sudo"):
        return 1
    else:
        error += 1
        return 0

while True:
    #如果错误次数等于3,则进入死循环,并不停输出"You didn't said the magic word!",否则重复执行while块,继续验证。
    if error == 3:
        print("You didn't said the magic word!")
        time.sleep(0.5)
    else:
        hack = input("Auth_Username:")
        #如果用户输入了正确的内容,则用break跳出循环
        if auth(hack) == 1:
            break

        print("Permission denid!")
#这个print是写在这两个if判断之后的,也就是当用户既没有输入正确的内容,
#也没有累计错误三次(即第一、二次输入错误)时,显示错误信息并重复执行while块

print("Dear administrator, welcome!")
#在第16行,当用户输入正确的内容时,会break跳出循环,则会执行以上内容
#输出成功信息,并退出程序。

做了点小修改,全局变量被拿掉了!

#!/usr/bin/python3
import time

def auth(username):
    if username == ("sudo"):
        return 1
    else:
        return 0

error = 0
while True:
    #如果错误次数等于3,则进入死循环,并不停输出"You didn't said the magic word!",否则重复执行while块,继续验证。
    if error == 3:
        print("You didn't said the magic word!")
        time.sleep(0.5)
    else:
        hack = input("Auth_Username: ")
        #如果用户输入了正确的内容,则用break跳出循环
        if auth(hack) == 1:
            break

        error += 1
        print("Permission denid!")
#这个print是写在这两个if判断之后的,也就是当用户既没有输入正确的内容,
#也没有累计错误三次(即第一、二次输入错误)时,显示错误信息并重复执行while块

print("Dear administrator, welcome!")
#在第16行,当用户输入正确的内容时,会break跳出循环,则会执行以上内容
#输出成功信息,并退出程序。

在 2013 年写了更多面向对象程序后,再次重写此段代码。

#!/usr/bin/env python3
from time import sleep


class UsernameAuthenticator():

    def __init__(self):
        self.__error_count = 0

    @property
    def error_count(self):
        return self.__error_count

    def auth(self, username):
        if username == "sudo":
            return True
        elif username != "sudo" or self.__error_count > 3:
            self.__error_count += 1
            return False


if __name__ == "__main__":
    auth = UsernameAuthenticator()
    while True:
        if auth.error_count >= 3:
            print("You didn't said the magic word!")
            sleep(0.5)
        elif auth.auth(input("Auth_Username: ")):
            print("Dear administrator, welcome!")
            break
        elif auth.error_count < 3:
            print("Permission denid!")

Categories: Python, 代码如诗

320GB硬盘摇身变成128GB(160GB)——硬盘造假防不胜防 » « 在用户使用代理,或者服务器使用反向代理或CDN的情况下,获得访客的正确IP

3 Comments

  1. 楼主为何不用只一个While?

1 Pingback

  1. drug store

发表评论

Your email address will not be published.

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax

Copyright © 2017 比尔盖子 博客

匿名浏览:http://x4wttqqrkud5pttgqlpxgevtr4rbqpa6lkwdiw3o3m6q4deeldgq.b32.i2p
警告:残留有明网混合资源,访问前请自行屏蔽明网流量

Theme by Anders NorenUp ↑