在本节中主要讨论在Python
网络爬虫逆向中常见的一些加密数据之间的相互转化及数据类型之间的相互转化。
主要包括以下内容:
ASCII
编码
Unicode
- 字符串
- 十进制数值
- 十六进制数值
- 二进制
base64
- 字节码
字符与ASCII编码之间的相互转化
字符转化为ASCII编码
1 2 3
| str1 = 'm' ascii_code = ord(str1) print(ascii_code)
|
ASCII编码转化为字符
1 2
| str1 = chr(ascii_code) print(str1)
|
由于字符串只能够对单个字符进行编码,如果想用ASCII
对字符串进行编码和解码则需要对字符串进行遍历。
原始的ASCII
编码表中没有的字符会自动使用Unicode
编码进行填充。
字符串ASCII
编码
1 2 3
| string = 'hello world!你好' ascii_string = [ord(i) for i in string] print(ascii_string)
|
ASCII
编码字符串解码
1 2
| string = ''.join([chr(i) for i in ascii_string]) print(string)
|
字符串与Unicode编码之间的相互转化
字符串转化为Unicode编码
1 2 3
| string = '你好,世界!' ucode_string = string.encode('unicode_escape').decode() print(ucode_string)
|
Unicode编码转化为字符串
1 2
| string = ucode_string.encode('utf-8').decode('unicode_escape') print(string)
|
字符串与字节码之间的相互转化
在python
中默认情况下字符串的编码是UTF-8
格式,如果是其他格式则需要在encode()
函数中传入其他参数。例如:encode('gbk')
。
字符串转化为字节码
1 2
| byte_string = string.encode() print(byte_string)
|
将字节码转化为字符串
1 2
| string = byte_string.decode('utf-8') print(string)
|
在网页数据传输中字符串肯定是用到最多的,我们在进行传输的时候为了使得我们传输的内容没有那么容器被其他人破译,一般不会直接传输明文,会对其进行简单的处理再传输。但是部分过程又不支持以字节码的形式进行传输,故我们一般是将其处理为十六进制或者Base64
格式然后再进行传输。
字节码与十六进制之间的相互转化
字节码转化为十六进制编码
1 2 3 4 5
| import binascii hex_string = binascii.b2a_hex(byte_string).decode() print(hex_string) hex_string = binascii.hexlify(byte_string).decode() print(hex_string)
|
十六进制编码转化为字节码
1 2 3 4
| string = binascii.a2b_hex(hex_string) print(string) string = binascii.unhexlify(hex_string) print(string)
|
字节码与base64编码之间的相互转化
字节码转化为base64编码
1 2 3
| import base64 base64_string = base64.b64encode(byte_string).decode() print(base64_string)
|
base64编码转化为字节码
1 2
| string = base64.b64decode(base64_string).decode() print(string)
|
十进制与十六进制之间的相互转化
十进制数值转化为十六进制
1 2 3 4 5
| num = 122 hex_num = hex(num) print(hex_num) hex_num = format(num, 'x') print(hex_num)
|
注意这两种情况得到的结果不太一样,hex()
函数获取到的结果中包含0x
字段。
可以将代码修改成如下格式,得到的结果就保持一致了:
1 2 3 4 5
| num = 122 hex_num = hex(num).replace('0x', '') print(hex_num) hex_num = format(num, 'x') print(hex_num)
|
十六进制转化为十进制
1 2
| num = int(hex_num, base=16) print(num)
|
十进制与二进制之间的相互转化
十进制转化为二进制
1 2 3 4
| bin_num = bin(num) print(bin_num) bin_num = format(num, 'b') print(bin_num)
|
与2.1
一样这两种方式得到的结果不一致,bin()
函数获取到的结果中包含0b
字段。
可修改为如下格式,使得结果保持一致。
1 2 3 4
| bin_num = bin(num).replace('0b', '') print(bin_num) bin_num = format(num, 'b') print(bin_num)
|
二进制转化为十进制
1 2
| num = int(bin_num, base=2) print(num)
|
十六进制与二进制之间的相互转化
十六进制与二进制之间的相互转化,只需要使用十进制进行中间过渡即可。
十六进制转化为二进制
1 2
| bin_num = format(int(hex_num, base=16), 'b') print(bin_num)
|
二进制转化为十六进制
1 2
| hex_num = format(int(bin_num, base=2), 'x') print(hex_num)
|
字符串加密
学习了这些转化规则后,我们就可以对字符串以及数值进行相关的加密了。
将字符串加密为十六进制编码
思路:字符串->
字节码->
十六进制
1 2 3 4 5
| import binascii
string = '如果你的眉眼,肯为我停留半分,又怎会不知我情比海深。' string_hex = binascii.b2a_hex(string.encode('utf-8')).decode() print(string_hex)
|
1
| e5a682e69e9ce4bda0e79a84e79c89e79cbcefbc8ce882afe4b8bae68891e5819ce79599e58d8ae58886efbc8ce58f88e6808ee4bc9ae4b88de79fa5e68891e68385e6af94e6b5b7e6b7b1e38082
|
特征:结果为a-f0-9
的组合。
解码:
1 2
| string = binascii.a2b_hex(string_hex).decode('utf-8') print(string)
|
1
| 如果你的眉眼,肯为我停留半分,又怎会不知我情比海深。
|
将字符串加密为Base64编码
思路:字符串->
字节码->
Base64编码
1 2 3 4
| import base64 string = '如果你的眉眼,肯为我停留半分,又怎会不知我情比海深。' string_b64= base64.b64encode(string.encode('utf-8')).decode() print(string_b64)
|
1
| 5aaC5p6c5L2g55qE55yJ55y877yM6IKv5Li65oiR5YGc55WZ5Y2K5YiG77yM5Y+I5oCO5Lya5LiN55+l5oiR5oOF5q+U5rW35rex44CC
|
特征:a-zA-Z0-9
,以及/
和+
组成 一共64个符号,有时候有=
用来占位。
解码:
1 2 3
| string = base64.b64decode(string_b64).decode('utf-8') print(string)
|
1
| 如果你的眉眼,肯为我停留半分,又怎会不知我情比海深。
|
数值加密
将数值转化为字符串,然后再使用字符串的加密方式。
使用str()
函数将数值转化为字符串,后续再使用字符串加密方式即可。
将数值转化为十六进制,再对十六进制字符串进行加密
使用hex()
或者format()
将数值转化为十六进制,再对十六进制字符串进行加密即可。
将数值转化为二进制,然后再对二进制进行位操作
将数值转化为二进制后取反进行加密
1 2 3 4
| num = 5201314 bin_num = format(num, 'b') min_bin_num = ''.join([str(int(i) ^ 1) for i in bin_num]) print(min_bin_num)
|
特征:由数字0
和1
构成
解密:
1 2 3
| bin_num = ''.join([str(int(i) ^ 1) for i in min_bin_num]) num = int(bin_num, base=2) print(num)
|