hashlib & hmac
*不是很清楚能不能把这种hash值取样算法称之为加密,但是似乎好像也是这么说的哈(非科班出身的野路子就是没这种基本知识的)
■ 基本用法
hashlib支持MD5,sha1等多种加密算法,详见hashlib.algorithms_available
用法十分简单:
m = hashlib.md5() #或者是其他算法的名字,如hashlib.sha1()
m.update("Some String") #加密用update方法,注意这个方法不会返回任何值,而是把加密解密操作封装在了m这个对象里面
print m.hexdigest() #一般查看加密后的密文用hexdigest方法
*关于update方法,还有一点要说。update("a")之后再update("b")并不是说把原先a的部分都抹掉再“更新”成b(which是update这个词本身的意思吧。。),而是相当于从最开始就update("ab")了。
hmac模块用法基本同上,但是在创建加密对象的时候需要传递一个key进去:
m = hmac.new("myownkey") #默认的加密算法是md5,如果需要用其他的算法,可以用digestmod参数,令其digestmod=hashlib.sha1 m.update("Some String") m.hexdigest() #显示加密后的密文
*m也可调用m.digest()方法,得到的是密文的“字符串形式二进制数据”。而上面提到的hexdigest方法只不过是把digest方法得到的密文通过hex编码生成了结果。相当于:
m.digest().encode("hex") 就是得到的 m.hexdigest()
同hex类似的另一种编码方式便是base64了。即m.digest().encode("base64")可以生成以base64格式编码的内容了?
**虽然同为编码方式,hex以及base64和之前我熟悉的utf-8,gbk,ascii这些编码不是一个概念。
utf-8,ascii这些编码主要用于将二进制数据和中文等自然语言的互相转换制定了一个标准
base64,hex这些则是制定了二进制数据和可以拿来进行网络传输的数据之间的互相转换的标准(比如把图片的二进制数据通过base64编码成一个字符串,这样看到这个字符串的人是不知道原来的图片是长什么样子的) //这个只是我个人YY出来的,下次有时间了仔细再去看一下详细解释,留个疑问吧
***話が変わるけど,这个hash值取出来之后应该首先是一串二进制数据对吧?然后再把这个数据通过某种编码方式编码之后,就是digest的产物了。也就是所谓的“字符串形式的二进制数据”。然后把这个字符串再通过hex或者base64的编码规则映射一下得到的就是最终的数据了。可以参考以下代码:
m = hashlib.md5() m.update("Some String") print type(m.digest()) print [m.digest()] #这里用列表而不是直接print是因为,print的话肯定会以某种默认的编码(或utf,或gbk,跟python shell的环境有关)显示出来,这样会乱码= =
而列表在print的时候可以直接显示内存中的内容。 print m.digest().encode("hex") print m.digest().encode("base64") ################输出################ <type 'str'> ['x83xbexb8xc4xfaEx96xc8xf7xb5exd3x90xf4x94xe2'] 83beb8c4fa4596c8f7b565d390f494e2 g764xPpFlsj3tWXTkPSU4g==
■ 关于linux的md5sum命令和python的hashlib
偶尔发现md5sum读取文件的MD5哈希值和通过python的hashlib算出来的不一致。这主要是换行符的锅。或者说,在windows上进行python的hashlib读取文件哈希值算出来的和在linux上算出来的不一样的。解决的办法就是在windows上使用update之前,保证被读入md5对象的值是通过rb模式打开文件读取到的内容:
import hashlib m = md5() with open('testfile','rb') as f: content = f.read() m.update(content) print m.hexdigest()