python模塊pyinstaller(打包)、PyCryptodome加密庫、binascii模塊、base64模塊、hashlib模塊(md5)、URL編碼


pyinstaller

pyinstaller -F python3_report.py
pyinstaller36 -F -p D:\my_python_project\my_spider\my_proxypool_spider\spider\NeteaseCloudMusic run.py#生成的dist文件夾再run.py所在的文件夾內
pyinstaller36 -F -p D:\my_python_project\my_spider\my_proxypool_spider\spider\NeteaseCloudMusic -i 1.ico run.py若文件中引入其他自定義模塊,需要用-p指定路徑(建議使用絕對路徑)

參數說明
-F, –onefile    打包一個單個文件,如果你的代碼都寫在一個.py文件的話,可以用這個,如果是多個.py文件就別用
-D, –onedir    打包多個文件,在dist中生成很多依賴文件,適合以框架形式編寫工具代碼,我個人比較推薦這樣,代碼易於維護
-p DIR, –path=DIR    設置導入路徑(和使用PYTHONPATH效果相似).可以用路徑分割符(Windows使用分號,Linux使用冒號)分割,指定多個目錄.也可以使用多個-p參數來設置多個導入路徑,讓pyinstaller自己去找程序需要的資源
–icon=<FILE.ICO>    
將file.ico添加為可執行文件的資源(只對Windows系統有效),改變程序的圖標  pyinstaller -i  ico路徑 xxxxx.py


查看exe運行時的錯誤:不要雙擊運行exe,使用cmd運行exe即可
pyinstaller

參考: https://blog.csdn.net/qq_35203425/article/details/78568141

 PyCryptodome加密庫

Base64編碼:是一種用64個字符來表示任意二進制數據的方法。
MD5(信息-摘要算法):固定長度,不可逆
AES加密#
1使用AES.new(key, AES.MODE_CFB, iv)獲取一個加密器對象,key為秘鑰,長度為16?;iv為偏移量
2.使用加密器對象的decrypt方法對文本進行加密,返回加密文本。

from binascii import b2a_hex
#from Crypto.Cipher import AES # for linux 在這里卡了很久。。。Windows ide環境下測試正常,但是windows打包成exe就是錯誤
#from Crypto import Random
from Cryptodome.Cipher import AES# for windows
from Cryptodome import Random

# 要加密的明文
data = '南來北往'
# 密鑰key 長度必須為16(AES-128)、24(AES-192)、或32(AES-256)Bytes 長度.
# 目前AES-128足夠用
key = b'this is a 16 key'
# 生成長度等於AES塊大小的不可重復的密鑰向量
iv = Random.new().read(AES.block_size)

# 使用key和iv初始化AES對象, 使用MODE_CFB模式
mycipher = AES.new(key, AES.MODE_CFB, iv)
# 加密的明文長度必須為16的倍數,如果長度不為16的倍數,則需要補足為16的倍數
# 將iv(密鑰向量)加到加密的密文開頭,一起傳輸
ciphertext = iv + mycipher.encrypt(data.encode())

# 解密的話要用key和iv生成新的AES對象
mydecrypt = AES.new(key, AES.MODE_CFB, ciphertext[:16])
# 使用新生成的AES對象,將加密的密文解密
decrypttext = mydecrypt.decrypt(ciphertext[16:])


print('密鑰k為:', key)
print('iv為:', b2a_hex(ciphertext)[:16])
print('加密后數據為:', b2a_hex(ciphertext)[16:])
print('解密后數據為:', decrypttext.decode())
PyCryptodome簡單示例
class Encryptor(object):
    modulus = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'
    nonce = '0CoJUm6Qyw8W8jud'
    pub_key = '010001'

    '''
        function a(a) {
            var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
            for (d = 0; a > d; d += 1)
                e = Math.random() * b.length,//獲取0-1之間的隨機數*b的長度
                e = Math.floor(e), //將e進行四舍五入
                c += b.charAt(e); //取字符串b的索引位e的字符,加入到c中
            return c
        }
    '''
    @classmethod
    def a(self, a):  # 這是我根據網易的js源碼寫的
        b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
        c = ''
        d = 0
        while a > d:
            e = random.random() * len(b)
            e = round(e) - 1
            c += b[e]
            d += 1
        return c

    import os
    # def a(size): #這是教程的版本,將會沒有大寫英文
    #     return binascii.hexlify(os.urandom(size))[:16]
    
    #------------------------------------------------------------------------------------------------------------------------------------------------

    '''
    //下載地址:https://github.com/brix/crypto-js/blob/master/docs/QuickStartGuide.wiki#AES
    <script src="crypto-js-svn-mirror-3.1.2/build/components/core.js"></script>
    <script src="crypto-js-svn-mirror-3.1.2/build/components/md5.js"></script>
    <script src="crypto-js-svn-mirror-3.1.2/build/components/evpkdf.js"></script>
    <script src="crypto-js-svn-mirror-3.1.2/build/components/enc-base64.js"></script>
    <script src="crypto-js-svn-mirror-3.1.2/build/components/cipher-core.js"></script>
    <script src="crypto-js-svn-mirror-3.1.2/build/components/aes.js"></script>
    <script src="crypto-js-svn-mirror-3.1.2/build/components/hmac.js"></script>
    <script src="crypto-js-svn-mirror-3.1.2/build/components/sha1.js"></script>
    <script src="crypto-js-svn-mirror-3.1.2/build/components/sha256.js"></script>
    
        function b(a, b) {
            var c = CryptoJS.enc.Utf8.parse(b)//key
              , d = CryptoJS.enc.Utf8.parse("0102030405060708")//iv
              , e = CryptoJS.enc.Utf8.parse(a) //加密的文本
              , f = CryptoJS.AES.encrypt(e, c, {
                iv: d,
                mode: CryptoJS.mode.CBC
            });
            return f.toString()
        }
        //b('12345','1234567812345678')# parse前的文本;perse前的key
    

    '''

    @classmethod
    def b(self, a, b):
        pad = 16 - len(a) % 16
        text = (a + chr(pad) * pad).encode()

        secKey = b.encode()
        iv = b"0102030405060708"

        mycipher = AES.new(secKey, AES.MODE_CBC, iv)
        ciphertext = mycipher.encrypt(text)
        ciphertext = base64.b64encode(ciphertext).decode()

        return ciphertext
        
    #------------------------------------------------------------------------------------------------------------------------------------------------

    '''
        function c(a, b, c) {
            var d, e;
            return setMaxDigits(131),
            d = new RSAKeyPair(b,"",c),
            e = encryptedString(d, a)
        }
    '''


    # binascii.hexlify 把二進制數據轉化為十六進制的數據展示,即每一個字節的數據轉換成相應的2位十六進制表示。因此產生的字串是源數據兩倍長度。a2b_hex和unhexlify則執行反向操作。
    @classmethod
    def c(self, text, pubKey, modulus):
        text = text[::-1]
        rs = pow(int(binascii.hexlify(text), 16), int(pubKey, 16), int(modulus, 16))
        return format(rs, 'x').zfill(256)
        
    #------------------------------------------------------------------------------------------------------------------------------------------------

    '''
        function d(d, e, f, g) {
            var h = {}
              , i = a(16);
            return h.encText = b(d, g),
            h.encText = b(h.encText, i),
            h.encSecKey = c(i, e, f),
            h
        }
    '''

    # def d(self,d,e,f,g):
    @classmethod
    def d(self, d):
        e = self.pub_key
        f = self.modulus
        g = self.nonce
        '''
        
        d需要動態傳入;efg都是常量
        :param d: text==JSON.stringify(i8a)

        :param e: pub_key = '010001'
        :param f: modulus = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'
        :param g: nonce = '0CoJUm6Qyw8W8jud'
        :return:
        '''
        text = json.dumps(d)
        sec_key = self.a(16)
        enc_text = self.b(text, g)
        params = self.b(enc_text, sec_key)  # 調用2次b方法得到params
        encSecKey = self.c(sec_key.encode(), e, f)  # 調用c方法得到encSecKey

        data = {
            'params': params,
            'encSecKey': encSecKey,
        }
        return data

        #更詳細筆記可見自己的網易雲音樂項目以及 https://github.com/Jack-Cherish/python-spider
網易雲音樂項目(js的CryptoJS加密以及使用Cryptodome對js的加密方法重構)

 

我們所說的加密方式,都是對二進制編碼的格式進行加密的,對應到Python中,則是我們的Bytes。
所以當我們在Python中進行加密操作的時候,要確保我們操作的是Bytes,否則就會報錯。

注:兩位十六進制常常用來顯示一個二進制字節。
binascii模塊可以將十六進制顯示的字節轉換成我們在加解密中更常用的顯示方式:

import binascii

s = '南北'.encode()  # b'\xe5\x8d\x97\xe5\x8c\x97'
binascii.b2a_hex(s)  # b'e58d97e58c97'
binascii.hexlify(s)  # 作用同上
binascii.a2b_hex(b'e58d97e58c97')  # b'\xe5\x8d\x97\xe5\x8c\x97'
binascii

 URL編碼其實就是將超出ASCII范圍的字符轉換成帶%的十六進制格式。

from urllib import parse

# quote()方法會自動將str轉換成bytes,所以這里傳入str和bytes都可以
print(parse.quote('南北'))#'%E5%8D%97%E5%8C%97'
print(parse.unquote('%E5%8D%97%E5%8C%97'))#南北
URL編碼

 

 Base64編碼

Base64是一種用65個(65字符:A~Z a~z 0~9 + / =)字符來表示任意二進制數據的方法。
Base64編碼可以成為密碼學的基石。可以將任意的二進制數據進行Base64編碼。編碼后的數據會變大,約為原本的4/3

import base64
print(base64.b64encode(b'hello world'))#b'aGVsbG8gd29ybGQ='
print(base64.b64decode(b'aGVsbG8gd29ybGQ='))#b'hello world'
Base64編碼

md5

md5,其實就是一種算法。可以將一個字符串,或文件,或壓縮包,執行md5后,就可以生成一個固定長度為128bit的串。這個串,基本上是唯一的。
import hashlib

str = '這是一個測試'
hl = hashlib.md5()# 創建md5對象
hl.update(str.encode(encoding='utf-8'))# 若寫法為hl.update(str)  報錯為: Unicode-objects must be encoded before hashing

print('MD5加密前為 :' + str)
print('MD5加密后為 :' + hl.hexdigest())#MD5加密后為 :cfca700b9e09cf664f3ae80733274d9f
MD5

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

最常見加密方式和Python實現: https://blog.csdn.net/qq_38473236/article/details/81263420

 

 

 

 

 

 

 

 

 

111111111


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM