Python核心程式設計 第七章 練習7–5
7–5. userpw2.py. 下面的問題和例題7.1 中管理名字-密碼的鍵值對資料的程式有關。
(a)修改那個指令碼,使它能記錄使用者上次的登入日期和時間(用time 模組),並與使用者密碼一起 儲存起來。程式的介面有要求使用者輸入使用者名稱和密碼的提示。無論戶名是否成功登入,都應有提示, 在戶名成功登入後,應更新相應使用者的上次登入時間戳。如果本次登入與上次登入在時間上相差不 超過4 個小時,則通知該使用者: “You already logged in at: .”
(b) 新增一個“管理”選單,其中有以下兩項:(1)刪除一個使用者 (2)顯示系統中所有使用者的名 字和他們的密碼的清單。
(c) 口令目前沒有加密。請新增一段對口令加密的程式碼(請參考crypt, rotor, 或其它加密模組)
(d) 為程式新增圖形介面,例如,用Tkinter 寫。
(e) 要求使用者名稱不區分大小寫。
(f) 加強對使用者名稱的限制,不允許符號和空白符。
(g)合併“新使用者”和“老使用者”兩個選項。如果一個新使用者試圖用一個不存在的使用者名稱登入,
詢問該使用者是否是新使用者,如果回答是肯定的,就建立該帳戶。否則,按照老使用者的方式登入。
原原本本的程式碼:
#!/usr/bin/env python
db = {}
def newuser():
prompt = 'login desired: '
while True:
name = raw_input(prompt)
if db.has_key(name):
prompt = 'name taken, try another: '
continue
else:
break
pwd = raw_input('passwd: ')
db[name] = pwd
def olduser():
name = raw_input('login: ')
pwd = raw_input('passwd: ')
passwd = db.get(name)
if passwd == pwd:
print 'welcome back', name
else:
print 'login incorrect'
def showmenu():
prompt = """
(N)ew User Login
(E)xisting User Login
(Q)uit
Enter choice: """
done = False
while not done:
chosen = False
while not chosen:
try:
choice = raw_input(prompt).strip()[0].lower()
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'neq':
print 'invalid menu option, try again'
else:
chosen = True
if choice == 'q': done = 1
if choice == 'n': newuser()
if choice == 'e': olduser()
if __name__ == '__main__':
showmenu()
(a)修改那個指令碼,使它能記錄使用者上次的登入日期和時間(用time 模組),並與使用者密碼一起 儲存起來。程式的介面有要求使用者輸入使用者名稱和密碼的提示。無論戶名是否成功登入,都應有提示, 在戶名成功登入後,應更新相應使用者的上次登入時間戳。如果本次登入與上次登入在時間上相差不 超過4 個小時,則通知該使用者: “You already logged in at: .”
#!/usr/bin/env python
from time import time,ctime #匯入模組
db = {}
def newuser():
prompt = 'login desired: '
while True:
name = raw_input(prompt)
if db.has_key(name):
prompt = 'name taken, try another: '
continue
else:
break
pwd = raw_input('passwd: ')#使用者名稱合格後,要求輸入密碼
logt=time()#獲取時間戳
db[name]=[pwd,logt]#把密碼和時間組成列表存到字典,共享一個鍵
def olduser():
name=raw_input('login: ')
pwd=raw_input('passwd: ')
if name in db:#檢測是否是老使用者
if pwd == db.get(name)[0]: #獲取老使用者密碼與輸入密碼比較
print 'welcome back',name #顯示歡迎資訊
print 'You lasttime logged in at:',ctime(db[name][1])
#顯示上次登入的時間戳
current=time()#獲取當前時間
delta=current-db[name][1]#求上次登入與現在時間的時間差
if delta<=14400: #判斷是否在4小時內
print 'You already logged in 4 hours period!'
else:#若時間差不在四小時之內
logt=time()#獲取當前時間
db[name][1]=logt #把密碼和時間組成列表存到字典,共享一個鍵,更新時間戳
else: #密碼錯誤
print 'login incorrect'
else: #不是老使用者
print 'login incorrect'
def showmenu():
prompt = """
(N)ew User Login
(E)xisting User Login
(Q)uit
Enter choice: """
done = False
while not done:
chosen = False
while not chosen:
try:
choice = raw_input(prompt).strip()[0].lower()
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'neq':
print 'invalid menu option, try again'
else:
chosen = True
if choice == 'q': done = 1
if choice == 'n': newuser()
if choice == 'e': olduser()
if __name__ == '__main__':
showmenu()
(b) 新增一個“管理”選單,其中有以下兩項:(1)刪除一個使用者 (2)顯示系統中所有使用者的名字和他們的密碼的清單。
#!/usr/bin/env python
from time import time,ctime #匯入模組
db = {}
def newuser():
prompt = 'login desired: '
while True:
name = raw_input(prompt)
if db.has_key(name):
prompt = 'name taken, try another: '
continue
else:
break
pwd = raw_input('passwd: ')
logt=time()
db[name]=[pwd,logt]
def olduser():
name=raw_input('login: ')
pwd=raw_input('passwd: ')
if name in db:
if pwd == db.get(name)[0]:
print 'welcome back',name
print 'You lasttime logged in at:',ctime(db[name][1])
current=time()
delta=current-db[name][1]
if delta<=14400: #判斷是否在4小時內
print 'You already logged in 4 hours period!'
else:
logt=time()#獲取當前時間
db[name][1]=logt #把密碼和時間組成列表存到字典,共享一個鍵
else:
print 'login incorrect'
else:
print 'login incorrect'
def deluser():
Getuserpwd()
c=raw_input('del a user,its name:')
if c in db.keys():
del db[c]
print 'After del:'
Getuserpwd()
else:
print 'Wrong choose!'
def Getuserpwd():
if db:
for name in db:
print 'name:',name,'pwd:',db[name][0]
else:
print 'No usr!'
def management():
prompt = """
(D)el a user
(G)et all user and pwd
(Q)uit
Enter choice: """
done = False
while not done:
chosen = False
while not chosen:
try:
choice = raw_input(prompt).strip()[0].lower()
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'gdq':
print 'invalid menu option, try again'
else:
chosen = True
if choice == 'q': done = 1
if choice == 'd': deluser()
if choice == 'g': Getuserpwd()
def showmenu():
prompt = """
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
Enter choice: """
done = False
while not done:
chosen = False
while not chosen:
try:
choice = raw_input(prompt).strip()[0].lower()
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'neqm':
print 'invalid menu option, try again'
else:
chosen = True
if choice == 'q': done = 1
if choice == 'n': newuser()
if choice == 'e': olduser()
if choice == 'm': management()
if __name__ == '__main__':
showmenu()
c)口令目前沒有加密. 請新增一段對口令加密的程式碼(請參考crypt,rotor,或其它加密模組)
#!/usr/bin/env python
from time import time,ctime #匯入模組
import base64#匯入加密模組
db = {}
def newuser():
prompt = 'login desired: '
while True:
name = raw_input(prompt)
if db.has_key(name):
prompt = 'name taken, try another: '
continue
else:
break
p1 = raw_input('passwd: ')#明文密碼
logt=time()
p2 = base64.encodestring(p1)#密文密碼
db[name]=[p2,logt]#儲存密文密碼
def olduser():
name=raw_input('login: ')
p1=raw_input('passwd: ')
if name in db:
p2=base64.decodestring(db[name][0])#解密所存密文
if p1 == p2 : #與使用者輸入密碼比對
print 'welcome back',name
print 'You lasttime logged in at:',ctime(db[name][1])
current=time()
delta=current-db[name][1]
if delta<=14400: #判斷是否在4小時內
print 'You already logged in 4 hours period!'
else:
logt=time()#獲取當前時間
db[name][1]=logt #把密碼和時間組成列表存到字典,共享一個鍵
else:
print 'login incorrect'
else:
print 'login incorrect'
def deluser():
Getuserpwd()
c=raw_input('del a user,its name:')
if c in db.keys():
del db[c]
print 'After del:'
Getuserpwd()
else:
print 'Wrong choose!'
def Getuserpwd():
if db:
for name in db:
print 'name:',name,'pwd:',db[name][0]
else:
print 'No user!'
def management():
prompt = """
(D)el a user
(G)et all user and pwd
(Q)uit
Enter choice: """
done = False
while not done:
chosen = False
while not chosen:
try:
choice = raw_input(prompt).strip()[0].lower()
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'gdq':
print 'invalid menu option, try again'
else:
chosen = True
if choice == 'q': done = 1
if choice == 'd': deluser()
if choice == 'g': Getuserpwd()
def showmenu():
prompt = """
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
Enter choice: """
done = False
while not done:
chosen = False
while not chosen:
try:
choice = raw_input(prompt).strip()[0].lower()
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'neqm':
print 'invalid menu option, try again'
else:
chosen = True
if choice == 'q': done = 1
if choice == 'n': newuser()
if choice == 'e': olduser()
if choice == 'm': management()
if __name__ == '__main__':
showmenu()
先貼一下前幾問的輸入輸出:
>>>
#主選單
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
#建立三個使用者
Enter choice: n
You picked: [n]
login desired: 1
passwd: 123
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
Enter choice: n
You picked: [n]
login desired: a
passwd: xyz
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
Enter choice: n
You picked: [n]
login desired: name999
passwd: 999name
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
#老使用者輸出錯誤密碼的情況
Enter choice: e
You picked: [e]
login: 1
passwd: abc
login incorrect
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
#錯誤選單選項的情況
Enter choice: 1
You picked: [1]
invalid menu option, try again
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
#老使用者登入成功,顯示上次登入時間,若在四小時內,列印提示資訊
Enter choice: e
You picked: [e]
login: 1
passwd: 123
welcome back 1
You lasttime logged in at: Sat Apr 04 17:14:15 2015
You already logged in 4 hours period!
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
#管理選單中的兩個子選單
Enter choice: m
You picked: [m]
(D)el a user
(G)et all user and pwd
(Q)uit
Enter choice: g
#獲得所有使用者和對應密碼,密碼是密文顯示
You picked: [g]
name: 1 pwd: MTIz
name: a pwd: eHl6
name: name999 pwd: OTk5bmFtZQ==
(D)el a user
(G)et all user and pwd
(Q)uit
Enter choice: d
#刪除一個使用者
You picked: [d]
name: 1 pwd: MTIz
name: a pwd: eHl6
name: name999 pwd: OTk5bmFtZQ==
del a user,its name:a
After del:
name: 1 pwd: MTIz
name: name999 pwd: OTk5bmFtZQ==
(D)el a user
(G)et all user and pwd
(Q)uit
#退出管理選單
Enter choice: q
You picked: [q]
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
#退出總選單
Enter choice: q
You picked: [q]
>>>
(d) 為程式新增圖形介面,例如,用Tkinter 寫。
正在收集資料,學習tkinter,以完成作業
(e) 要求使用者名稱不區分大小寫。
思路:選單選項的寫法給我啟發,設定將使用者名稱輸入轉換為小寫就好。
#!/usr/bin/env python
from time import time,ctime #匯入模組
import base64
db = {}
def newuser():
prompt = 'login desired: '
while True:
name = raw_input(prompt).strip()[0].lower()#設定小寫
if db.has_key(name):
prompt = 'name taken, try another: '
continue
else:
break
p1 = raw_input('passwd: ')
logt=time()
p2 = base64.encodestring(p1)
db[name]=[p2,logt]
def olduser():
name=raw_input('login: ').strip()[0].lower()#設定小寫
p1=raw_input('passwd: ')
if name in db:
p2=base64.decodestring(db[name][0])
if p1 == p2 :
print 'welcome back',name
print 'You lasttime logged in at:',ctime(db[name][1])
current=time()
delta=current-db[name][1]
if delta<=14400: #判斷是否在4小時內
print 'You already logged in 4 hours period!'
else:
logt=time()#獲取當前時間
db[name][1]=logt #把密碼和時間組成列表存到字典,共享一個鍵
else:
print 'login incorrect'
else:
print 'login incorrect'
def deluser():
Getuserpwd()
c=raw_input('del a user,its name:').strip()[0].lower()#設定小寫
if c in db.keys():
del db[c]
print 'After del:'
Getuserpwd()
else:
print 'Wrong choose!'
def Getuserpwd():
if db:
for name in db:
print 'name:',name,'pwd:',db[name][0]
else:
print 'No user!'
def management():
prompt = """
(D)el a user
(G)et all user and pwd
(Q)uit
Enter choice: """
done = False
while not done:
chosen = False
while not chosen:
try:
choice = raw_input(prompt).strip()[0].lower()
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'gdq':
print 'invalid menu option, try again'
else:
chosen = True
if choice == 'q': done = 1
if choice == 'd': deluser()
if choice == 'g': Getuserpwd()
def showmenu():
prompt = """
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
Enter choice: """
done = False
while not done:
chosen = False
while not chosen:
try:
choice = raw_input(prompt).strip()[0].lower()
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'neqm':
print 'invalid menu option, try again'
else:
chosen = True
if choice == 'q': done = 1
if choice == 'n': newuser()
if choice == 'e': olduser()
if choice == 'm': management()
if __name__ == '__main__':
showmenu()
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
Enter choice: n
You picked: [n]
login desired: a
passwd: 1
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
Enter choice: e
You picked: [e]
login: A
passwd: 1
welcome back a
You lasttime logged in at: Sat Apr 04 19:12:15 2015
You already logged in 4 hours period!
(f) 加強對使用者名稱的限制,不允許符號和空白符。
思路:除了符號和空白符。那就理解為使用者名稱應該由 數字和大小寫字母組成。
#!/usr/bin/env python
from time import time,ctime #匯入模組
import base64
import string #匯入string模組
db = {}
y=string.letters+string.digits#限定只能是數字和大小寫字母
def newuser():
prompt = 'login desired,only accept digits and letters: '
while True:
name = raw_input(prompt).strip()[0].lower()
if name in y:#驗證
if db.has_key(name):
prompt = 'name taken, try another: '
continue
else:
break
else:
print 'Invalid name!'
p1 = raw_input('passwd: ')
logt=time()
p2 = base64.encodestring(p1)
db[name]=[p2,logt]
def olduser():
name=raw_input('login: ').strip()[0].lower()
p1=raw_input('passwd: ')
if name in db:
p2=base64.decodestring(db[name][0])
if p1 == p2 :
print 'welcome back',name
print 'You lasttime logged in at:',ctime(db[name][1])
current=time()
delta=current-db[name][1]
if delta<=14400: #判斷是否在4小時內
print 'You already logged in 4 hours period!'
else:
logt=time()#獲取當前時間
db[name][1]=logt #把密碼和時間組成列表存到字典,共享一個鍵
else:
print 'login incorrect'
else:
print 'login incorrect'
def deluser():
Getuserpwd()
c=raw_input('del a user,its name:').strip()[0].lower()
if c in db.keys():
del db[c]
print 'After del:'
Getuserpwd()
else:
print 'Wrong choose!'
def Getuserpwd():
if db:
for name in db:
print 'name:',name,',pwd:',db[name][0]
else:
print 'No user!'
def management():
prompt = """
(D)el a user
(G)et all user and pwd
(Q)uit
Enter choice: """
done = False
while not done:
chosen = False
while not chosen:
try:
choice = raw_input(prompt).strip()[0].lower()
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'gdq':
print 'invalid menu option, try again'
else:
chosen = True
if choice == 'q': done = 1
if choice == 'd': deluser()
if choice == 'g': Getuserpwd()
def showmenu():
prompt = """
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
Enter choice: """
done = False
while not done:
chosen = False
while not chosen:
try:
choice = raw_input(prompt).strip()[0].lower()
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'neqm':
print 'invalid menu option, try again'
else:
chosen = True
if choice == 'q': done = 1
if choice == 'n': newuser()
if choice == 'e': olduser()
if choice == 'm': management()
if __name__ == '__main__':
showmenu()
(N)ew User Login
(E)xisting User Login
(M)anagement
(Q)uit
Enter choice: n
You picked: [n]
login desired,only accept digits and letters: @1
Invalid name!
login desired,only accept digits and letters: a
passwd: 1
(g)合併“新使用者”和“老使用者”兩個選項。如果一個新使用者試圖用一個不存在的使用者名稱登入,詢問該使用者是否是新使用者,如果回答是肯定的,就建立該帳戶。否則,按照老使用者的方式登入。
思路:釋放了原來的兩個函式的直接呼叫
建立一個Userlog函式來一次呼叫就行了。新增一些判斷。
#!/usr/bin/env python
from time import time,ctime #匯入模組
import base64
import string
db = {}
y=string.letters+string.digits
def newuser():
prompt = 'login desired,name only accept digits and letters: '
while True:
name = raw_input(prompt).strip()[0].lower()
if name in y:
if db.has_key(name):
prompt = 'name taken, try another: '
continue
else:
break
else:
print 'Invalid name!'
p1 = raw_input('passwd: ')
logt=time()
p2 = base64.encodestring(p1)
db[name]=[p2,logt]
def olduser():
name=raw_input('login: ').strip()[0].lower()
p1=raw_input('passwd: ')
if name in db:
p2=base64.decodestring(db[name][0])
if p1 == p2 :
print 'welcome back',name
print 'You lasttime logged in at:',ctime(db[name][1])
current=time()
delta=current-db[name][1]
if delta<=14400: #判斷是否在4小時內
print 'You already logged in 4 hours period!'
else:
logt=time()#獲取當前時間
db[name][1]=logt #把密碼和時間組成列表存到字典,共享一個鍵
else:
print 'login incorrect'
else:#當輸入的使用者名稱和密碼不是註冊過的,列印提升資訊:是否註冊?
w=raw_input('register it(Y/N)?').strip()[0].lower()
if 'y' == w:
newuser()#若選擇註冊,呼叫新使用者註冊函式
else:
print 'login incorrect'
def userlog():#userlog函式首先預設呼叫老使用者登入函式
olduser()
def deluser():
Getuserpwd()
c=raw_input('del a user,its name:').strip()[0].lower()
if c in db.keys():
del db[c]
print 'After del:'
Getuserpwd()
else:
print 'Wrong choose!'
def Getuserpwd():
if db:
for name in db:
print 'name:',name,',pwd:',db[name][0]
else:
print 'No user!'
def management():
prompt = """
(D)el a user
(G)et all user and pwd
(Q)uit
Enter choice: """
done = False
while not done:
chosen = False
while not chosen:
try:
choice = raw_input(prompt).strip()[0].lower()
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'gdq':
print 'invalid menu option, try again'
else:
chosen = True
if choice == 'q': done = 1
if choice == 'd': deluser()
if choice == 'g': Getuserpwd()
def showmenu():
prompt = """
(U)ser Login
(M)anagement
(Q)uit
Enter choice: """
done = False
while not done:
chosen = False
while not chosen:
try:
choice = raw_input(prompt).strip()[0].lower()
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'uqm':
print 'invalid menu option, try again'
else:
chosen = True
if choice == 'q': done = 1
if choice == 'u': userlog()
if choice == 'm': management()
if __name__ == '__main__':
showmenu()
(U)ser Login
(M)anagement
(Q)uit
Enter choice: u
You picked: [u]
login: 1
passwd: 1
register it(Y/N)?y
login desired,name only accept digits and letters: pythON
passwd: c++
(U)ser Login
(M)anagement
(Q)uit
Enter choice: u
You picked: [u]
login: PYthon
passwd: c++
welcome back p
You lasttime logged in at: Sat Apr 04 19:55:51 2015
You already logged in 4 hours period!