python模块pyinstaller(打包)、PyCryptodome加密库、binascii模块、base64模块、hashlib模块(md5)、URL编码

岁酱吖の 提交于 2020-04-27 18:31:17

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!