我们经常需要对内容进行加密传输、或者跟服务器交互的时候签名,验证信息的真伪。常见的方法:base64转码、urlencode编码、进制间互转、MD5
求hash、AES加密等。在python中的实现方式,笔录如下:
[TOC]
base64在python中
字符串转base64
在python3中,字符都是unicode编码格式,base64.b64encode的参数需为byte类型,需要先做转换。
import base64
_str = 'abcde' # 待编码字符
_str2b64 = base64.b64encode( _str.encode('utf-8') )
print(_str2b64) # b'YWJjZGU='
输出是:b'YWJjZGU='
这里b的意思是byte的意思,需要再次转换:
_str2b64 = str(_str2b64 ,'utf-8')
print(_str2b64 ) #YWJjZGU=
base64转字符串
将base64转会字符串,只需要用base64.b64decode( b64 )
,演示如下:
linux命令行转换
echo '字符串'|base64
输出5a2X56ym5LiyCg==
;
逆转:echo '5a2X56ym5LiyCg==' |base64 -d
。
这种方法的好处是不需要写代码,命令行轻松搞定。
URLDECODE与URLENCODE编码解码
一般都是用urllib库实现的,把python中的字典转化为请求参数的形式:
import urllib.parse
values={}
values['username']='02蔡彩虹'
values['password']='ddddd?'
url="http://www.baidu.com"
data=urllib.parse.urlencode(values)
print(data)
username=02%E8%94%A1%E5%BD%A9%E8%99%B9&password=ddddd%3F
如果你只想对字符串进行编码,可以使用quote()
:
_str = '要转码的字符串abcde123&&*'
print( urllib.parse.quote(_str) )
# %E8%A6%81%E8%BD%AC%E7%A0%81%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2abcde123%26%26%2A
urldecode解码
使用urllib.parse.unquote()
方法即可
print( urllib.parse.unquote( urllib.parse.quote(_str) ) )
# 要转码的字符串abcde123&&*
MD5计算哈希
非堆成加密计算签名时常用。
import hashlib
def md5( pass_text):
hl = hashlib.md5()
hl.update(pass_text.strip().encode(encoding='utf-8'))
pass_md5 = hl.hexdigest()
return pass_md5
print( md5('一段字符串') )
MD5无法逆转,校验结果也只是对加密后的内容进行字符串比较。
进制转换
hex转字符串
a = 'aabbccddeeff'
a_bytes = bytes.fromhex(a)
print(a_bytes)
# b'\xaa\xbb\xcc\xdd\xee\xff'
aa = a_bytes.hex()
print(aa)
# aabbccddeeff
# bytes转字符串方式一
b=b'\xe9\x80\x86\xe7\x81\xab'
string=str(b,'utf-8')
print(string)
# bytes转字符串方式二
b=b'\xe9\x80\x86\xe7\x81\xab'
string=b.decode() # 第一参数默认utf8,第二参数默认strict
print(string)
# bytes转字符串方式三
b=b'\xe9\x80\x86\xe7\x81haha\xab'
string=b.decode('utf-8','ignore') # 忽略非法字符,用strict会抛出异常
print(string)
# bytes转字符串方式四
b=b'\xe9\x80\x86\xe7\x81haha\xab'
string=b.decode('utf-8','replace') # 用?取代非法字符
print(string)
# 字符串转bytes方式一
str1='逆火'
b=bytes(str1, encoding='utf-8')
print(b)
# 字符串转bytes方式二
b=str1.encode('utf-8')
print(b)
更多(转载)
进行协议解析时,总是会遇到各种各样的数据转换的问题,从二进制到十进制,从字节串到整数等等
整数之间的进制转换:
10进制转16进制: hex(16) ==> 0x10
16进制转10进制: int('0x10', 16) ==> 16
类似的还有oct()
, bin()
字符串转整数:
10进制字符串:int('10') ==> 10
16进制字符串: int('10', 16) ==> 16
16进制字符串: int('0x10', 16) ==> 16
字节串转整数:
转义为short型整数: struct.unpack('<hh', bytes(b'\x01\x00\x00\x00')) ==> (1, 0)
转义为long型整数: struct.unpack('<L', bytes(b'\x01\x00\x00\x00')) ==> (1,)
整数转字节串:
转为两个字节: struct.pack('<HH', 1,2) ==> b'\x01\x00\x02\x00'
转为四个字节: struct.pack('<LL', 1,2) ==> b'\x01\x00\x00\x00\x02\x00\x00\x00'
字符串转字节串:
字符串编码为字节码: '12abc'.encode('ascii') ==> b'12abc'
数字或字符数组: bytes([1,2, ord('1'),ord('2')]) ==> b'\x01\x0212'
16进制字符串: bytes().fromhex('010210') ==> b'\x01\x02\x10'
16进制字符串: bytes(map(ord, '\x01\x02\x31\x32')) ==> b'\x01\x0212'
16进制数组: bytes([0x01,0x02,0x31,0x32]) ==> b'\x01\x0212'
字节串转字符串:
字节码解码为字符串: bytes(b'\x31\x32\x61\x62').decode('ascii') ==> 12ab
字节串转16进制表示,夹带ascii: str(bytes(b'\x01\x0212'))[2:-1] ==> \x01\x0212
字节串转16进制表示,固定两个字符表示: str(binascii.b2a_hex(b'\x01\x0212'))[2:-1] ==> 01023132
字节串转16进制数组: [hex(x) for x in bytes(b'\x01\x0212')] ==> ['0x1', '0x2', '0x31', '0x32']