---
# System prepended metadata

title: password code

---

# password code
- (1/2 update method3 & for lipnet check)

## for lipnet
``` python=
#
# 一開始開啟時要輸入密碼
# 換密碼 可以敲鍵盤
# 你輸入了幾個字，密碼是幾個字
# 如果是句子的話，錯第幾個字，數字的話就不用
# 屬空格跟數字數，
# 一碰到錯的話就跳開，句子的話，從第幾個字就錯
# 輸入阿拉伯數字，儲存的時候轉成字母並無空格。比對的時候也是把空格去掉，只要有92%以上的相似率就給過

#方案們

# 1.	把正確密碼與辨認的句子分割成一個個單字，以單字為單位辨認。
# 優點：可以告訴使用者錯了哪個字
# 缺點：如果辨認出的句字單字斷在錯的地方，後面的單字也會對應錯誤

# 2.	把正確密碼與辨認出的字串個別全部combine成一個字串，一個個字母比對
# 缺點：如果差一個字後面就全錯了
# 優點：可以告訴使用者字數、錯了哪個字，但如果差一個字後面就全錯了
# Ps.可以用在純數字?

# 3.	與1.相同變成一個字串，使用python-Levenshtein模組來判定兩個字串整體的相似度。
# 缺點：無法告訴使用者錯了哪個字
# 優點：如果辨識出的句子有空缺還是可以辨識兩個句子的相似度

import time
import Levenshtein
# import RPi.GPIO as GPIO
# LED_PIN = [3]
#SWITCH_PIN = [11]
# GPIO.setmode(GPIO.BOARD)

#GPIO.setup(SWITCH_PIN, GPIO.IN)
# GPIO.setup(LED_PIN, GPIO.OUT)


password=[]
pushbutton=True



def setpassword():  #set password if there is older passsword,user need to enter the older one,or user can't change
    print("setpassword()")
    a1 = input("please choose what kind of your pasword, 1:numbers 2:letter 3:sentence")
    
    if a1=='1': #set the number password ,turn the number to letters
        print("setpassword:number")
        s=''
        number_letter={'1':'one','2':'two','3':'three','4':'four','5':'five','6':'six','7':'seven','8':'eight','9':'nine','0':'zero'}
        if password == []:
            x = input("please input your password: ")
            for i in x:
                s+=(number_letter[i]+' ')
            password.append(s)  
                
            for pas in password:
                print(pas)
                
            print("the type of password is : ") #test
            print(type(password[0]))

        else:
            y=input("please input the older password: ")
            if password_check1(y,password)!=0:
                x = input("please input new password: ")
                password.pop()
                for i in x:
                    s+=(number_letter[i]+' ')  #翻譯成英文單字後連成字串儲存
                password.append(s) 
                return 0
                
    elif a1=='2':
        
        print("setpassword:letter")
        s=''
        
        if password == []:
            x = input("please input your password: ")
            for i in x:
                s+=(i+' ')  #以字串儲存
            password.append(s)       
            for pas in password:
                print(pas)
                
        else:
            x=input("please input the older password: ")
            if password_check1(x,password)!=0:
                password.pop()
                x = input("please input your password: ")
                for i in x:  #以字串儲存
                    s+=(i+' ')
                password.append(s)
                return 0
            
            else:
                print("Wrong,plese try again")
        
    elif a1=='3':
        print("setpassword:sentence")
        
        
        if password == []:
            x = input("please input your password: ")
            password.append(x)      #直接儲存輸入字串 
            for pas in password:
                print(pas)
                
        else:
            x=input("please input the older password: ")
            if password_check1(x,password)!=0:
                password.pop()
                x = input("please input new password: ")
                password.append(x)
                return 0
            
            else:
                print("Wrong,plese try again")
                
        
    # if password == []:
    #     x = input("please input your password")
    #     password.append(x)
    #     print("the type of password is : ")
    #     print(type(password[0]))

    # else:
    #     x=input("please input the order password")
    #     for i in range(len(password)):
    #         if x == password[i]:
    #             x1=input("please input the new password")
    #             password.remove(x)
    #             password.append(x1)
    #             return 0

    #     print("Wrong,plese try again")
    return 0


def password_check1(test,password):  #分割成單字
    
    test1=test.split(' ')
    password1=password[0].split(' ')
    print(type(password1))
    print(type(test1))
    
    diff=int(len(password1)-len(test1))
    print(diff)
    test1.extend("" for _ in range(diff)) #如果輸入密碼太短把它補成跟原本密碼同樣長度
    
    #test
    print("test is: ")
    print(test1)
    
    print("password1 is: ")
    print(password1)
    
    wrong=[]
    for i in range(len(password1)):
        # print("password[%d] is %s" %(i,password1[i]))
        # print("test1[%d] is %s" %(i,test1[i]))
        if test1[i]!=password1[i]:
            # print(" |%s| != |%s|" %(password1[i],test1[i]))
            wrong.append(str(i+1)) #把錯第幾個字存起來
        
    if wrong:
        print("The password is wrong.")
        
        print("The lenth you input %d words" %(len(test.split(' ')))) #告訴user輸入了幾個字
        print("The password's lenth is %d words" %(len(password1)))  #正確密碼幾個字
        
        print("No.{} word is wrong".format(" ".join(wrong)))  #錯了第幾個字
        # #for i in range(len(wrong)):
        # print(" ".join(wrong))

        # print(" is wrong.")
        
        
        return 0

    else:
        #GPIO.output(LED_PIN[0], GPIO.HIGH)
        time.sleep(1.5) #delay 1.5 seconds
        print("The password is right.")
        
        return 1
        
        
def password_check2(test,password): #組合成一個字串
    
    test1=test.split(' ')
    s1=""
    test2=s1.join(test1)
    print(test2) #test
    
    password1=s1.join(password[0].split(' '))
    print(password1) #test
    
    diff=int(len(password1)-len(test2))
    print(diff)
    
    if diff<0:
        bigger=len(test2)
        password1+="0"*(-diff)
    else:
        bigger=len(password1)
        test2+="0"*diff
    
    wrong=[]
    for i in range(bigger):
        if test2[i]!=password1[i]:
            wrong.append(str(i+1))
            
    if wrong:
        print("The password is wrong.")
        print("The lenth you input %d words" %(len(s1.join(test1))))
        print("The password's lenth is %d words" %(len(s1.join(password[0].split(' '))))) 
        
        print("No.{} word is wrong".format(" ".join(wrong)))  #錯了第幾個字母
        
        
        return 0
        
    else:
        #GPIO.output(LED_PIN[0], GPIO.HIGH)
        time.sleep(1.5) #delay 1.5 seconds
        print("The password is right,you can enter.")
        return 1

import Levenshtein

def password_check3(test,password): #組合成一個字串
    
    test1=test.split(' ')
    s1=""
    test2=s1.join(test1)
    print("test2 is {}".format(test2))
    #print("password is {}".format(password)) #test
    password1=s1.join(password[0].split(' '))
    print("password1 is {}".format(password1))
    print("Levenshtein.ratio is {}".format(Levenshtein.ratio(test2,password1)))
    ratio = Levenshtein.ratio(test2,password1)   #計算萊文斯坦比。計算公式為 r = (sum - ldist) / sum, 其中sum是指str1 和 str2 字串的長度總和，ldist是類編輯距離。   
    if ratio < 0.7: #若相似度不夠則顯示錯誤
        print("The password is wrong.")
        print("The lenth you input %d words" %(len(test2)))
        print("The password's lenth is %d words" %(len(password1))) 
        print("The Levenshtein ratio is {}".format(ratio))
        return 0
        
        
    else:
        #GPIO.output(LED_PIN[0], GPIO.HIGH)
        time.sleep(1.5) #delay 1.5 seconds

        print("The password is right,you can enter.")
        return 1


try:
    
    while True:
        

        print('''\nif you want to set password,enter "1".if you want to enter,push the button''')

        c= input()
        print(type(c))
        print("c is {}".format(c))
        if c=='1':
            setpassword()


        if pushbutton: #之後改成 GPIO.input(SWITCH_PIN[0]) == GPIO.HIGH
            test=input("""please input the password,then you can open the door. """)
            password_check3(test,password)


            
                    
except KeyboardInterrupt:
    print("kb")
#finally:
    #GPIO.cleanup()


```


## method 3
- 前置作業：安裝 python-Levenshtein 模組
```
pip install python-Levenshtein
```
- function:

```python=
import Levenshtein

def password_check3(test,password): #組合成一個字串
    
    test1=test.split(' ')
    s1=""
    test2=s1.join(test1)
    print("test2 is {}".format(test2))
    #print("password is {}".format(password)) #test
    password1=s1.join(password[0].split(' '))
    print("password1 is {}".format(password1))
    print("Levenshtein.ratio is {}".format(Levenshtein.ratio(test2,password1)))
    ratio = Levenshtein.ratio(test2,password1)   #計算萊文斯坦比。計算公式為 r = (sum - ldist) / sum, 其中sum是指str1 和 str2 字串的長度總和，ldist是類編輯距離。   
    if ratio < 0.8: #若相似度不夠則顯示錯誤，可再視情況調整ratio
        print("The password is wrong.")
        print("The lenth you input %d words" %(len(test2)))
        print("The password's lenth is %d words" %(len(password1))) 
        print("The Levenshtein ratio is {}".format(ratio))
        return 0
        
        
    else:
        #GPIO.output(LED_PIN[0], GPIO.HIGH)
        time.sleep(1.5) #delay 1.5 seconds

        print("The password is right,you can enter.")
        return 1
```
- **python-Levenshtein introduction**:
    - *Levenshtein distance*：萊文斯坦距離，又稱Levenshtein距離，是編輯距離的一種。 指兩個字串之間，由一個轉成另一個所需的最少編輯操作次數。 允許的編輯操作包括將一個字元替換成另一個字元，插入一個字元，刪除一個字元。
    - *ratio*：計算萊文斯坦比。計算公式為 r = (sum - ldist) / sum, 其中sum是指str1 和 str2 字串的長度總和，ldist是類編輯距離。這裡的類編輯距離不是2中所說的編輯距離，2中三種操作中每個操作+1，而在此處，刪除、插入依然+1，但是替換+2，這樣ratio(‘a’, ‘c’)，sum=2，按2中計算為（2-1）/2 = 0.5，’a’，’c’沒有重合，顯然不合算，但是替換操作+2，就可以解決這個問題。
    - reference: https://iter01.com/604993.html
## method1&2
```python=
# coding=utf-8
# input25.avi fps=15
# input26.avi fps=10
# input27.avi fps=5
import cv2
import time
import numpy as np


#import Levenshtein

import RPi.GPIO as GPIO
LED_PIN = [3]
COUNTER_PIN = 16 
GPIO.setmode(GPIO.BOARD)
GPIO.setup(COUNTER_PIN, GPIO.IN)


password=[]
pushbutton=True


# 重設密碼：數字 abc 句子
def setpassword():  #set password if there is older passsword,user need to enter the older one,or user can't change
    print("setpassword()")
    a1 = input("please choose what kind of your pasword, 1:numbers 2:letter 3:sentence")
    
    if a1=='1': #set the number password ,turn the number to letters
        print("setpassword:number")
        s=''
        number_letter={'1':'one','2':'two','3':'three','4':'four','5':'five','6':'six','7':'seven','8':'eight','9':'nine','0':'zero'}
        if password == []:
            x = raw_input("please input your password: ")
            for i in x:
                s+=(number_letter[i]+' ')
            password.append(s)  
                
            for pas in password:
                print(pas)
                
            print("the type of password is : ") #test
            print(type(password[0]))

        else:
            y=input("please input the older password: ")
            if password_check1(y,password)!=0:
                x = input("please input new password: ")
                password.pop()
                for i in x:
                    s+=(number_letter[i]+' ')  #翻譯成英文單字後連成字串儲存
                password.append(s) 
                return 0
                
    elif a1=='2':
        
        print("setpassword:letter")
        s=''
        
        if password == []:
            x = input("please input your password: ")
            for i in x:
                s+=(i+' ')  #以字串儲存
            password.append(s)       
            for pas in password:
                print(pas)
                
        else:
            x=input("please input the older password: ")
            if password_check1(x,password)!=0:
                password.pop()
                x = input("please input your password: ")
                for i in x:  #以字串儲存
                    s+=(i+' ')
                password.append(s)
                return 0
            
            else:
                print("Wrong,plese try again")
        
    elif a1=='3':
        print("setpassword:sentence")
        
        
        if password == []:
            x = input("please input your password: ")
            password.append(x)      #直接儲存輸入字串 
            for pas in password:
                print(pas)
                
        else:
            x=input("please input the older password: ")
            if password_check1(x,password)!=0:
                password.pop()
                x = input("please input new password: ")
                password.append(x)
                return 0
            
            else:
                print("Wrong,plese try again")
                
        
    return 0


def password_check1(test,password):  #分割成單字
    
    test1=test.split(' ')
    password1=password[0].split(' ')
    print(type(password1))
    print(type(test1))
    
    diff=int(len(password1)-len(test1))
    print(diff)
    test1.extend("" for _ in range(diff)) #如果輸入密碼太短把它補成跟原本密碼同樣長度
    
    #test
    print("test is: ")
    print(test1)
    
    print("password1 is: ")
    print(password1)
    
    wrong=[]
    for i in range(len(password1)):
        # print("password[%d] is %s" %(i,password1[i]))
        # print("test1[%d] is %s" %(i,test1[i]))
        if test1[i]!=password1[i]:
            # print(" |%s| != |%s|" %(password1[i],test1[i]))
            wrong.append(str(i+1)) #把錯第幾個字存起來
        
    if wrong:
        print("The password is wrong.")
        
        print("The lenth you input %d words" %(len(test.split(' ')))) #告訴user輸入了幾個字
        print("The password's lenth is %d words" %(len(password1)))  #正確密碼幾個字
        
        print("No.{} word is wrong".format(" ".join(wrong)))  #錯了第幾個字
        
        bottom = False
        return bottom
        # return 0

    else:
        #GPIO.output(LED_PIN[0], GPIO.HIGH)
        time.sleep(1.5) #delay 1.5 seconds
        print("The password is right.")
        bottom = False
        return bottom 
        # return 1
        
        
def password_check2(test,password): #組合成一個字串
    
    test1=test.split(' ')
    s1=""
    test2=s1.join(test1)
    print(test2) #test
    password1=s1.join(password[0].split(' '))
    print(password1) #test
    
    diff=int(len(password1)-len(test2))
    print(diff)
    
    if diff<0:
        bigger=len(test2)
        password1+="0"*(-diff)
    else:
        bigger=len(password1)
        test2+="0"*diff
    
    wrong=[]
    for i in range(bigger):
        if test2[i]!=password1[i]:
            wrong.append(str(i+1))
            
    if wrong:
        print("The password is wrong.")
        print("The lenth you input %d words" %(len(s1.join(test1))))
        print("The password's lenth is %d words" %(len(s1.join(password[0].split(' '))))) 
        
        print("No.{} word is wrong".format(" ".join(wrong)))  #錯了第幾個字母
        
        
        return 0
        
    else:
        #GPIO.output(LED_PIN[0], GPIO.HIGH)
        time.sleep(1.5) #delay 1.5 seconds
        print("The password is right,you can enter.")
        return 1

 


def detector(filename):
    face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    img = cv2.imread(filename)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = face_cascade.detectMultiScale(gray,1.1,4)
    
    if len(faces) == 0:
        detect = False
    else:
        detect = True

    return detect


def camerarecording():
    # 读取设备，picamera跟webcam分別對應0跟1
    cap = cv2.VideoCapture(0) 
    # 读取摄像头FPS
    cap.set(cv2.CAP_PROP_FPS, 25)
    # set dimensions 设置分辨率
    # cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    # cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
    fourcc = cv2.VideoWriter_fourcc(*'XVID')

    print('get the bottom sign && start recording!')
    out = cv2.VideoWriter('input47(2525).avi', fourcc, 25, (100, 50))
    
    
    while cap.isOpened():
        ret, frame = cap.read()
        out.write(frame)
        cv2.imwrite('image.jpg', frame)
        detect = detector('image.jpg')
        print('decting')

        if detect != True:
            bottom = False
            content.append(bottom)
            print('no faces, stop recording!')
            out.release()
            cap.release()
            break


try:   
    content = [False]
    bottom = False
    while True:
        
        if  GPIO.input(COUNTER_PIN) == GPIO.HIGH:
            print('''\nif you want to set password,enter "1".if you want to enter,push the button''')
            c=input()
            if c=='1':
                setpassword()
        
            bottom = True
            content.append(bottom)
            
        if content[-1] == True:
            bottom = False # 等待下一次按按鈕
            camerarecording()
            # 轉檔 、丟入資料夾
            # model inference
            # 密碼確認
            password_check1(test,password) #test接inference result

except KeyboardInterrupt:
        print('interrupt')

finally:
    cv2.destroyAllWindows()


# todo task
# (1) 自動轉成.mpg
# (2) 丟入modle inference 
# (3) output 比對
# (4) correct or back to the top




```