# Python實作課程
## 第七堂課 : Password Manager
## 2022 / 6 / 17
### Tony
---
# 古典密碼
## 維吉尼亞密碼
a.k.a進階版凱薩密碼
----
加密原理 :
明文、密鑰:由字母組成的字串
把 A 到 Z 編號成 0 到 25
明文中第一個字母的位移量就是密鑰第一個字母的**編號**、
第二個字母的位移量就是密鑰第二個字母的**編號**、……
如果密鑰長度比明文字母數短
就再從**第一個字母**開始用
----
明文:HSNU CRC
密鑰:CRSC
**明文 H S N U C R C**
密鑰 C R S C C R S
密文 J J F W E I U
----
因為每一個字母的位移量都不盡相同
所以不知道密鑰的情況下
要還原出明文是很困難的事
幾乎不可能
----
## 維吉尼亞表格

---
# 實作維吉尼亞密碼
----
要怎麼把字母位移?
----
我們利用**ASCII**(美國資訊交換標準代碼)

----
找到字元 c 對應的數字:ord(c)
找到數字 i 對應的字元:chr(i)
----
純字母版
```python=
def encryption(key, password):
cipher = ""
now = 0
for char in password:
t = ord(char) - ord('A')
k = ord( key[now] ) - ord('A')
print(t+k)
cipher += chr( ord('A') + (t+k)%26 )
now = (now + 1) % len(key)
return cipher
def decryption(key, password):
cipher = ""
now = 0
for char in password:
t = ord(char) - ord('A')
k = ord( key[now] ) - ord('A')
print(t-k)
cipher += chr( ord('A') + (t-k)%26)
now = (now + 1) % len(key)
return cipher
```
----
廣泛版(不局限於字母)
```python=
def encryption(key, password):
cipher = ""
now = 0
for char in password:
k = ord( key[now] ) - ord('A')
cipher += chr( (ord(char) + k)%126 )
now = (now + 1) % len(key)
return cipher
def decryption(key, password):
cipher = ""
now = 0
for char in password:
k = ord( key[now] ) - ord('A')
cipher += chr( (ord(char) - k)%126 )
now = (now + 1) % len(key)
return cipher
```
我們將用它來加密/解密我們的密碼
---
# Password Manager
----
有時候在很多網站創建很多帳號
其中每種帳號的密碼限制都不一樣
時間久了很容易忘記
這種時候就很需要Password Manager的幫忙
----
Process:
1. 輸入Master password (用戶名,也是到時候加解密的key)
2. 選擇瀏覽密碼還是新增密碼
3. 如果新增密碼,輸入帳號名稱跟密碼,把密碼依照維吉尼亞密碼規定加密後連同帳號名稱存入記事本
4. 如果瀏覽密碼,把目前所有的密碼解密之後連同帳號名稱秀出來
5. 都沒事了就按q退出
如果master password輸入錯誤,就會無法看到既有的密碼
---
# 開始寫Code
----
1. 輸入master password
```python=
key = input("What is the master password?")
```
----
2. 選擇瀏覽密碼還是加新密碼
```python=
while True:
mode= input("Would you like to add a new password or view existing ones (view, add), press q to quit? ").lower()
if mode == 'q':
break
if mode == "view":
view(key)
elif mode == "add":
add(key)
else:
print("Valid mode.")
continue
```
----
加解密函式
```python=
def encryption(key, password):
cipher = ""
now = 0
for char in password:
k = ord( key[now] ) - ord('A')
cipher += chr( (ord(char) + k)%126 )
now = (now + 1) % len(key)
return cipher
def decryption(key, password):
cipher = ""
now = 0
for char in password:
k = ord( key[now] ) - ord('A')
cipher += chr( (ord(char) - k)%126 )
now = (now + 1) % len(key)
return cipher
```
----
add()函式
在`password.txt` 中新加一條密碼,包含用戶名稱跟密碼
* `with open("password.txt", 'a') as file:`
打開一個文件檔並做事情,把他想成一個if
執行結束之後`password.txt`就會自動被關掉,很方便
輸入完會請使用者再確認一次
----
```python=
def add(key):
print('')
Done = False
while not Done:
name = input("Account name : ")
password = input("Password : ")
print('')
print("Please double check the account name and password you\'ve typed in :")
print("Account name :", name)
print("Password :", password)
correct = input("Type \"yes\" if they're correct, \"no\" if they're not : ").lower()
print('')
if correct == "yes":
encrypted_password = encryption(key, password)
# like a function. Once it's done, the file will be closed automatically.
# a stands for "pen". Add sth to an existing file or create a new file if the file doesn't exist.
# w stands for "write". Create a file or overwrite the file
# r stands for "read". Just read.
with open("password.txt", 'a') as file:
file.write(name + '|' + encrypted_password + '\n') # 寫入密碼
Done = True
elif correct == "no":
print("Alright. Please type again.")
continue
else:
print("Valid reaction.")
continue
```
----
`view()`函式
把目前所有密碼都依照輸入的key解密後秀出來
* `file.readlines(len)` : 取得文字檔file的所有文字,len默認是-1,代表所有行數
* `line.split('|')` : 把line依照'|'切割成n個不同字元,大多數密碼不會包含'|',所以假設只利用原先用來分割的'|'切割出兩個字串
* `line.rstrip()` : 去除line最後面的指定部分,默認是空白、換行等等
----
```python=
def view(key):
print('')
with open("password.txt", 'r') as file:
for line in file.readlines():
data = line.rstrip() # delete the '\n' behind ecery line
user, password = data.split('|') # "FB|123456789" -> ["FB", "123456789"]
password = decryption(key, password)
print("Account name :", user, "| Password :", password)
print('')
```
恭喜各位完成Password Manager,
可以自己多加一些有趣的功能
{"metaMigratedAt":"2023-06-17T03:02:06.461Z","metaMigratedFrom":"YAML","title":"Python實作五:Password Manager","breaks":true,"slideOptions":"{\"transition\":\"slide\",\"theme\":null}","contributors":"[{\"id\":\"4f731eff-9d88-41f4-af56-2e3e02f20cfc\",\"add\":5188,\"del\":57}]"}