哈希及文件操做

1.哈希 hashpython

在将文件操做的方法以前,咱们先来对上节的知识作一个拓展,就是哈希算法,那么什么是哈希算法呢?算法

(1)哈希:hash,通常翻译作散列、杂凑,或音译为哈希,是把任意长度的输入(又叫作预映射pre-image)经过散列算法变换成固定长度的输出,该输出就是散列值。数据库

这种转换是一种压缩映射,也就是,散列值的空间一般远小于输入的空间。函数

哈希算法的输入能够是字符串,能够是数据,能够是任何文件,通过哈希运算后,都变成一个固定长度的输出,该输出就是哈希值。区块链

>>> hash('我爱你')
3471388576844338423
>>> hash('小猿圈')
5000768010434506639

如上所示,输入“我爱你”三个字,通过哈希运算后,会获得一个随机数列,并且无论你的输入文件多大,最后获得的结果都是这么一个固定长度的数列,即便你输入的是一部电影,输出也是这么大。编码

 

(2)特性:加密

  1.不可逆性:在具有编码功能的同时,哈希算法也做为一种加密算法存在。即,你没法经过分析哈希值计算出源文件的样子。spa

  不管是什么形式,任意大小的输入,最终结果都是一串长度相等的随机数列,所以你没法经过哈希值来推断数据本来的样子。翻译

  2.计算极快:不管是一个5G的电影仍是一个5k的文件,运用哈希算法计算量都极小,很快就能够计算出哈希值。code

 

(3)用途:

哈希算法的不可逆特性使其在如下领域使用普遍

  1. 密码,咱们平常使用的各类电子密码本质上都是基于hash的,你不用担忧支付宝的工做人员会把你的密码泄漏给第三方,由于你的登陆密码是先通过 hash+各类复杂算法得出密文后 再存进支付宝的数据库里的

  2. 文件完整性校验,经过对文件进行hash,得出一段hash值 ,这样文件内容之后被修改了,hash值就会变。 MD5 Hash算法的”数字指纹”特性,使它成为应用最普遍的一种文件完整性校验和(Checksum)算法,很多Unix系统有提供计算md5 checksum的命令。

  3. 数字签名,数字签名技术是将摘要信息用发送者的私钥加密,与原文一块儿传送给接收者。接收者只有用发送者的公钥才能解密被加密的摘要信息,而后用HASH函数对收到的原文产生一个摘要信息,与解密的摘要信息对比。若是相同,则说明收到的信息是完整的,在传输过程当中没有被修改,不然说明信息被修改过,所以数字签名可以验证信息的完整性。

此外,hash算法在区块链领域也使用普遍。

 

(4)在Python中基于HASH的数据类型是dict (字典)和set (集合)。以前说到的字典查询速度极快,以及集合天生去重就是运用了hash的特性。如下能够做一下了解。

1.dict查询速度快

假设一个dict中有不少信息,dict会将每个key进行哈希,将全部的哈希值按照从大到小的顺序放到一个列表中,如keys=[ -22,-10,11,23,99]

当须要查找某个信息时,dict将被查找信息的key进行哈希,同一个输入值进行哈希获得的哈希值时相等的,所以只需再列表中找到这个哈希值,就能找到对应的value。

那么问题来了,若是字典的数据比较小,计算机就能很快找到对应的值,可是若是字典中有几十亿条数据,怎么快速的找到对应的值呢?

dict采用的是二分法查找,即将被查找信息的key的哈希值与列表的中间的值比较大小,这样就能够舍弃一半的值,这样搜索区间就小了不少,多进行几回这样的操做,很快就能够找到对应的值。

这就是字典为什么查询速度快的基本原理,固然真实的算法会复杂的多。

 

2.set 天生去重

由于每存一个值到set里时, 都要先通过hash,而后经过得出的这个hash值算出应该存在set里的哪一个位置,存的时候会先检查那个位置上有没有值 ,

有的话就对比是否相等,若是相等,则再也不存储此值。 若是不相等(即为空),则把新值存在这。

 

2.文件操做

Python的文件操做基本经过如下步骤

f = open(filename)  # 打开文件

f.write("hello world")  # 写操做

f.read( )  # 读操做

f.close( )  # 保存并关闭文件

经常使用操做模式

python文件有三种基本的操做模式

r 只读模式

w 建立模式,不能读,用此模式操做,新的内容会覆盖旧的内容。即清空原来的内容,写入新的内容。

a 追加模式 ,写入的内容会追加到文件最后

只读模式

 

f = open('filename.text', 'r') f.readline() # 读一行内容
content = f.read()  # 读全部剩下的内容
print(content) f.close()

 

建立模式

f = open('filename.text', 'w') f.write('hello world')  # 此时该文件的内容为hello world(无论原文件内容是什么)
f.close()

追加模式

 

f = open('filename.text', 'a') f.write("小猿圈")  # 此时文件内容为 hello world小猿圈
f.close()

循环文件

f = open('filename.tesxt' , 'r') for line in f:  # 遍历文件的每一行
    print(line)

 

文件的其余操做功能

 

f = open('filename.text', 'r') f.mode # 返回文件的打开方式
 f.name # 返回文件名
 f.fileno() # 返回文件句柄在内核中的索引值,之后作IO多路复用时能够用到
 f.flush() #将内容写入硬盘时,因为硬盘的处理速度慢,内容会先在内存中,达到必定数量一# 起写入硬盘提高效率,flush()方法可将内存中的数据写入硬盘
 f.readable() # 判断文件是否可读
 f.readline() # 只读一行,遇到\r 或 \n为止
 f.seek() # 把操做文件的光标移动到指定位置 seek的长度是按字节算的 不一样的编码方式每 #个字符所占的字节不一样。如gbk编码下中文字符占两个字节,utf-8编码下中文字符占三个字 #节,若是读取文件时的编码方式不一样会致使错误产生。
 f.seekable() # 判断文件是否能进行 seek 操做
 f.tell() # 返回当前文件操做光标的位置
 f.truncate() # 按指定长度截取文件  # 指定长度的话,就从文件开头开始截断指定长度; # 不指定长度的话,就从光标当前位置到文件 # 尾部的内容全去掉。
 f.writeable() # 判断文件是否可写

 

 

混合模式

文件打开还有三种混合模式,既能够读也能够写。

w+ 写读 ,它会建立一个新文件 ,写一段内容,能够再把写的内容读出来,通常不用。

r+ 读写,能读能写,但都是写在文件最后,跟追加同样,用的较多。

a+ 追加读,文件一打开时光标会在文件尾部,写的数据全会是追加的形式。

 

w+模式

 

f=open('filename.text','w+')  # w+读取时 光标在最后一行 读取时须要指定光标
 f.write("alex 23 male") f.seek(0) # 将光标移至开头 再读取
 print(f.readline()) f.close()

 

 

 

r+模式

f = open('filename', 'r+') f.write() # 默认往文件尾部写
f.readline()  # 读的是第一行

 

r+模式会将内容自动往文件末尾写,可是若是想修改数据应该怎么办?

将光标移动到中间的某一个位置,插入一个信息,会发现原来的信息会被写入的信息所覆盖。缘由是,当你将文件存到硬盘上时,就在硬盘上划分了一段空间,空间就那么大,当你想写入新的内容时,就只能覆盖掉原来的数据,而不能使数据总体向后移。

若是想要修改文件,就只能将文件加载到内存当中,数据在内存当中能够随便增删改查,以后再将修改完的数据存入硬盘覆盖掉原来的数据,就完成了文件的修改。

 注:r+使用时,该文件必须存在。

 

当你想修改一份特别大的文件的时候,一下把文件加载到内存,是一种不明智的方式。若是想不占内存,能够采用一边读一边写的方式,就是建立一个新的文件,一边从原文件中读,一边写入新的文件。

f_name = "filename.txt" f_new_name = "%s.new" % f_name old_str = "eric" new_str = "alex" f = open(f_name,'r')  # 打开原文件
f_new = open(f_new_name,'w')  # 建立一个新文件
for line in f:  # 读原文件
    if old_str in line: new_line = line.replace(old_str,new_str)  # 修改文件
    else: new_line = line f_new.write(new_line) 写入新文件 f.close() f_new.close()

 

 

 

注:以上内容部分参考自路飞学城。

相关文章
相关标签/搜索