Python筆記2_替換式文本加密

本文爲觀看教學視頻後的筆記整理,原教程來自嗶哩嗶哩愛可可愛生活
有時間的小夥伴可以去看一看,老師那裏還有很多比較基礎的教程

點擊此處,進入Github獲取下方代碼的完整 JupyterNotebook 文件

TIPS

str.index()  #找索引
help()  #多用help
%pdb  #輔助調試
assert('')#bool表達式驗證
ord('!')#獲取字符的ASCII碼
random.shuffle()
list.copy()#列表的淺拷貝,直接賦值會指向同一空間,原表會被改掉
dir(random)#查看成員函數

辨析局部變量與全局變量

a = 1

def mytest1():
    a = 2
    print(a)
mytest1()
print(a)

def mytest2():
    global a
    a = 2
    print(a)
mytest2()
print(a)

文字替換一:簡單替換加密

版本一:樸實無華版

聲明字母表,並用替換的方式建立新的字母表

alphabet_src = "abcdefghijklmnopqrstuvwxyz"#起名要注意可讀性,變量名用_,函數名用駝峯式
alphabet_tar = "defghijklmnopqrstuvwxyzabc"

定義待加密文本

src_str = 'hello world!'

加密過程

encrypted_str = ''
for single_char in src_str:
    if single_char in alphabet_src:
        index = alphabet_src.index(single_char)
        encrypted_str = encrypted_str + alphabet_tar[index]
    else:
        encrypted_str = encrypted_str + single_char
print(encrypted_str)

結果:
在這裏插入圖片描述

解密過程

decryped_str = ''
for single_char in encrypted_str:
    if single_char in alphabet_tar:
        index = alphabet_tar.index(single_char)
        decryped_str = decryped_str + alphabet_src[index]
    else:
        decryped_str = decryped_str + single_char
print(decryped_str)

結果:
在這裏插入圖片描述

版本二:用函數封裝代碼段

alphabet_src = "abcdefghijklmnopqrstuvwxyz"#起名要注意可讀性,變量名用_,函數名用駝峯式
alphabet_tar = "defghijklmnopqrstuvwxyzabc"

注意體會封裝性

def encryptIt(src_str):
    encrypted_str = ''
    for single_char in src_str:
        if single_char in alphabet_src:
            index = alphabet_src.index(single_char)
            encrypted_str = encrypted_str + alphabet_tar[index]
        else:
            encrypted_str = encrypted_str + single_char
    return encrypted_str

def decryptIt(encrypted_str):
    decryped_str = ''
    for single_char in encrypted_str:
        if single_char in alphabet_tar:
            index = alphabet_tar.index(single_char)
            decryped_str = decryped_str + alphabet_src[index]
        else:
            decryped_str = decryped_str + single_char
    return decryped_str
print(encryptIt("I love you!"))#不同邏輯之間隔開
print(decryptIt("I oryh brx!"))    

結果:
在這裏插入圖片描述

版本三:加入全局變量–增強可讀性

alphabet_src = "abcdefghijklmnopqrstuvwxyz"#起名要注意可讀性,變量名用_,函數名用駝峯式
alphabet_tar = "defghijklmnopqrstuvwxyzabc"
def encryptIt(src_str):
    global alphbet_src,alphabet_tar#全局變量
    encrypted_str = ''
    for single_char in src_str:
        if single_char in alphabet_src:
            index = alphabet_src.index(single_char)
            encrypted_str = encrypted_str + alphabet_tar[index]
        else:
            encrypted_str = encrypted_str + single_char
    return encrypted_str

def decryptIt(encrypted_str):
    global alphbet_src,alphabet_tar#全局變量
    decryped_str = ''
    for single_char in encrypted_str:
        if single_char in alphabet_tar:
            index = alphabet_tar.index(single_char)
            decryped_str = decryped_str + alphabet_src[index]
        else:
            decryped_str = decryped_str + single_char
    return decryped_str
print(encryptIt("I love you!"))#不同邏輯之間隔開
print(decryptIt("I oryh brx!"))  

結果:
在這裏插入圖片描述

版本四:加入自定義函數的help說明+亂序

alphabet_src = "abcdefghijklmnopqrstuvwxyz"#起名要注意可讀性,變量名用_,函數名用駝峯式
alphabet_tar = "defopquvghnwxyrstzabcijklm"

自己編寫的help適用於多人協作,增強代碼的可讀性。另外要儘量寫英文,少使用中文。

def encryptIt(src_str:str) -> str:
    '''Encrypt string -- Simple replacement encryption 
    Input parameters:
      src_str:original text
    Return result:encrypted text
    '''
    global alphbet_src,alphabet_tar#全局變量
    encrypted_str = ''
    for single_char in src_str:
        if single_char in alphabet_src:
            index = alphabet_src.index(single_char)
            encrypted_str = encrypted_str + alphabet_tar[index]
        else:
            encrypted_str = encrypted_str + single_char
    return encrypted_str

def decryptIt(encrypted_str:str) -> str:
    '''Decrypt string -- Simple replacement decryption 
    Input parameters:
      src_str:encrypted text
    Return result:original text
    '''
    global alphbet_src,alphabet_tar 
    decryped_str = ''
    for single_char in encrypted_str:
        if single_char in alphabet_tar:
            index = alphabet_tar.index(single_char)
            decryped_str = decryped_str + alphabet_src[index]
        else:
            decryped_str = decryped_str + single_char
    return decryped_str
print(encryptIt("I love you!"))#不同邏輯之間隔開
print(decryptIt("I wrip lrc!"))  

結果:
在這裏插入圖片描述

help(encryptIt)

結果:
在這裏插入圖片描述

help(decryptIt)

結果:
在這裏插入圖片描述

版本五:用索引實現串的替換

使用索引就可以少定義一個字母表了,同時便於隨時更改加密方式

alphabet_src = "abcdefghijklmnopqrstuvwxyz"#起名要注意可讀性,變量名用_,函數名用駝峯式
def encryptIt(src_str:str) -> str:
    '''Encrypt string -- Simple replacement encryption 
    Input parameters:
      src_str:original text
    Return result:encrypted text
    '''
    global alphbet_src,alphabet_tar#全局變量
    result = ''
    for single_char in src_str:
        if single_char in alphabet_src:
            old_index = alphabet_src.index(single_char)
            new_index = (old_index + 3) % 26
            result = result + alphabet_src[new_index]
        else:
            result = result + single_char
    return result

def decryptIt(encrypted_str:str) -> str:
    '''Decrypt string -- Simple replacement decryption 
    Input parameters:
      src_str:encrypted text
    Return result:original text
    '''
    global alphbet_src,alphabet_tar 
    result = ''
    for single_char in encrypted_str:
        if single_char in alphabet_src:
            old_index = alphabet_src.index(single_char)
            new_index = (old_index - 3) % 26
            result = result + alphabet_src[new_index]
        else:
            result = result + single_char
    return result
print(encryptIt("I love you!"))#不同邏輯之間隔開
print(decryptIt("I oryh brx!"))  

結果:
在這裏插入圖片描述

版本六:壓縮代碼長度

有時候我們可以讓代碼更精簡。

alphabet_src = "abcdefghijklmnopqrstuvwxyz"#起名要注意可讀性,變量名用_,函數名用駝峯式
def cryptIt(src_str:str,if_decrypt:bool = False) -> str:
    '''Encrypt and Decrypr string -- Simple replacement encryption 
    Input parameters:
      src_str:original text
      if_decrypt:True--Encrypt,False--Decrypt
    Return result:encrypted or decrypted text
    '''
    global alphbet_src,alphabet_tar#全局變量
    result = ''
    for single_char in src_str:
        if single_char in alphabet_src:
            new_index = (alphabet_src.index(single_char) - 3) % 26 \
                if if_decrypt is True \
                else (alphabet_src.index(single_char) + 3) % 26 #字符移位替換
            result += alphabet_src[new_index]
        else:
            result += single_char
    return result
print(cryptIt("I love you!",True))#不同邏輯之間隔開
print(cryptIt("I ilsb vlr!"))  

結果:
在這裏插入圖片描述

版本七:再壓縮–列表推導式

思考: 代碼一定是越精簡越好嗎?

alphabet_src = "abcdefghijklmnopqrstuvwxyz"#起名要注意可讀性,變量名用_,函數名用駝峯式
def cryptIt(src_str:str,if_decrypt:bool = False) -> str:
    '''Encrypt and Decrypr string -- Simple replacement encryption 
    Input parameters:
      src_str:original text
      if_decrypt:True--Encrypt,False--Decrypt
    Return result:encrypted or decrypted text
    '''
    global alphbet_src,alphabet_tar#全局變量
    return ''.join([alphabet_src[(alphabet_src.index(single_char) - 3) % 26 \
                if if_decrypt is True \
                else (alphabet_src.index(single_char) + 3) % 26] if \
                single_char in alphabet_src else single_char \
                for single_char in src_str])
print(cryptIt("I love you!",True))#不同邏輯之間隔開
print(cryptIt("I ilsb vlr!"))  

結果:
在這裏插入圖片描述

版本八:(對比六、七)適當壓縮但不影響可讀性與交互性

代碼長度要兼顧簡潔性與可讀性。

alphabet_src = "abcdefghijklmnopqrstuvwxyz"#起名要注意可讀性,變量名用_,函數名用駝峯式
def convert_char(single_char,operation):
    global alphabet_src
    if single_char in alphabet_src:
        old_index = alphabet_src.index(single_char)
        if operation == 'encrypt':
            new_index = (old_index + 3) % 26
        else:
            new_index = (old_index - 3) % 26
    else:
        return single_char
    return alphabet_src[new_index]

def encrypt_it(src_str:str) -> str:
    '''Encrypt string -- Simple replacement encryption 
    Input parameters:
      src_str:original text
    Return result:encrypted text
    '''
    #列表推導式,局部封裝
    encrypted_str = ''.join([convert_char(single_char,'encrypt') for single_char in src_str])
    return encrypted_str

def decrypt_it(encrypted_str:str) -> str:
    '''Decrypt string -- Simple replacement decryption 
    Input parameters:
      src_str:encrypted text
    Return result:original text
    '''
    #列表推導式,局部封裝
    decrypted_str = ''.join([convert_char(single_char,'decrypt') for single_char in encrypted_str])
    return decrypted_str
assert(decrypt_it(encrypt_it('abdkwe')) == 'abdkwe')#對互反性進行驗證
print(encrypt_it("I love you!"))#不同邏輯之間隔開
print(decrypt_it("I oryh brx!"))  

結果:
在這裏插入圖片描述

文字加密進階:可交付的隨機加密

版本一:用ASCII碼實現偏移置換(33-26)

不同於上方的只能加密字母的代碼,使用ASCII碼甚至可以加密符號。

def convert_char(single_char,operation):
    OFFSET = 10
    if ord(single_char) >=33 and ord(single_char) <=126:
        if operation == 'encrypt':
            result = chr((ord(single_char) -33 + OFFSET) % (126 -33 + 1) + 33)
        else:
            result = chr((ord(single_char) -33 - OFFSET) % (126 -33 + 1) + 33)
    else:
        return single_char
    return result

def encrypt_it(src_str:str) -> str:
    '''Encrypt string -- Simple replacement encryption 
    Input parameters:
      src_str:original text
    Return result:encrypted text
    '''
    #列表推導式,局部封裝
    encrypted_str = ''.join([convert_char(single_char,'encrypt') for single_char in src_str])
    return encrypted_str

def decrypt_it(encrypted_str:str) -> str:
    '''Decrypt string -- Simple replacement decryption 
    Input parameters:
      src_str:encrypted text
    Return result:original text
    '''
    #列表推導式,局部封裝
    decrypted_str = ''.join([convert_char(single_char,'decrypt') for single_char in encrypted_str])
    return decrypted_str
assert(decrypt_it(encrypt_it('abdkwe')) == 'abdkwe')#對互反性進行驗證
print(encrypt_it("I love you!"))#不同邏輯之間隔開
print(decrypt_it("S vy\"o %y!+"))  

結果:
在這裏插入圖片描述

版本二:強化加密可靠性-亂序

import random
alphabet_src = [chr(i) for i in range(33,127)]
alphabet_tar = alphabet_src.copy()
random.shuffle(alphabet_tar) 
def convert_char(single_char,operation):
    global alphabet_src
    if single_char in alphabet_src:
        if operation == 'encrypt':
            result = alphabet_tar[alphabet_src.index(single_char)]
        else:
            result = alphabet_src[alphabet_tar.index(single_char)]
    else:
        result = single_char
    return result

def encrypt_it(src_str:str) -> str:
    '''Encrypt string -- Simple replacement encryption 
    Input parameters:
      src_str:original text
    Return result:encrypted text
    '''
    #列表推導式,局部封裝
    encrypted_str = ''.join([convert_char(single_char,'encrypt') for single_char in src_str])
    return encrypted_str

def decrypt_it(encrypted_str:str) -> str:
    '''Decrypt string -- Simple replacement decryption 
    Input parameters:
      src_str:encrypted text
    Return result:original text
    '''
    #列表推導式,局部封裝
    decrypted_str = ''.join([convert_char(single_char,'decrypt') for single_char in encrypted_str])
    return decrypted_str
assert(decrypt_it(encrypt_it('abdkwe')) == 'abdkwe')#對互反性進行驗證,不報錯就是ok
print(encrypt_it("I love you!"))#不同邏輯之間隔開
print(decrypt_it("9 N{3$ S{~r")) 

結果:
在這裏插入圖片描述
思考: 這樣的亂序法會帶來怎樣的弊端?

版本三:實現交付–對文件的操作

版本二中的亂序加密,只能在一臺電腦中使用,原因在於我們使用了隨機數的生成。如果將加密後的文本發送給其他人,收件人根本就無法找出正確的加密規律。所以我們要把加密後的字母表存入文件,將該文件與加密後的文本一起發給收件人。

import pickle

!ls < test.txt
!more < test.txt

f = open('key.dat','wb')
f.write(pickle.dumps([alphabet_src,alphabet_tar]))
f.close()

import random
alphabet_src = [chr(i) for i in range(33,127)]
alphabet_tar = alphabet_src.copy()
random.shuffle(alphabet_tar) 

with open('key.dat','wb') as f:#這樣忘記close也不要緊
    f.write(pickle.dumps([alphabet_src,alphabet_tar]))
with open('key.dat','rb') as f:#這樣忘記close也不要緊
    print(pickle.loads(f.read()))

pickle.dump(
    [alphabet_src,alphabet_tar]
    open('key1.dat','wb')
)

!ls < key1.dat
!more < key1.dat

pickle.load(open('key1.dat','rb'))

感謝你的閱讀~
如有疑問,可以直接評論或私聊我~
點擊此處,進入Github獲取上述代碼的完整 JupyterNotebook 文件

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章