📯Python dict和set的底层原理
2022-5-26
| 2022-6-10
0  |  阅读时长 0 分钟
type
status
password
date
slug
summary
category
URL
tags
icon
dict是用来存储键值对结构的数据的,set其实也是存储的键值对,只是默认值是相同的。Python中的dict和set都是通过散列表来实现的。

hash计算

hash函数:每一个kernel都会有不同的结果

hashlib函数

Python 的 hashlib 提供了常见的摘要算法,如 MD5,SHA1 等等。摘要算法又称哈希算法、散列算法。它通过一个函数,把任意长度的数据转换为一个长度固定的数据串。

md5(每一个kernel不会改变结果)

MD5 是最常见的摘要算法,速度很快,生成结果是固定的 128 bit 字节,通常用一个 32 位的 16 进制字符串表示。

sha1函数

调用 SHA1 和调用 MD5 完全类似,SHA1 的结果是160 bit 字节,通常用一个 40 位的 16 进制字符串表示。

sha256

运行结果:

sha512

sha512 算法用起来和前面讲的 MD5,sha1,sha256 算法一样,都是同样的接口
运行结果:
SHA256 算法比 SHA1 算法更安全,SHA512 算法比 SHA1 算法更安全,越安全的算法计算速度越慢,摘要更长

pbkdf2_hmac

hashlib.pbkdf2_hmac 加盐:
运行结果:
hashlib.pbkdf2_hmac 第一个参数是哈希函数,这里使用的是 sha256,前面讲过的哈希函数都可以使用,比如将第一个参数改为 “sha512”

PBKDF2 函数原理

PBKDF2 介绍

PBKDF2(Password-Based Key Derivation Function) 是一个用来导出密钥的函数,常用于生成加密的密码。它的基本原理是通过一个伪随机函数(例如 HMAC 函数),把明文和一个盐值作为输入参数,然后重复进行运算,并最终产生密钥。如果重复的次数足够大,破解的成本就会变得很高。而盐值的添加也会增加“彩虹表”攻击的难度。

PBKDF2 函数的定义

  • PRF 是一个伪随机函数,例如 HASH_HMAC 函数,它会输出长度为 hLen 的结果。
  • Password 是用来生成密钥的原文密码。
  • Salt 是一个加密用的盐值。
  • c 是进行重复计算的次数。
  • dkLen 是期望得到的密钥的长度。
  • DK 是最后产生的密钥。

PBKDF2 算法流程

DK 的值由一个以上的 block 拼接而成。block 的数量是 dkLen/hLen 的值。就是说如果 PRF 输出的结果比期望得到的密钥长度要短,则要通过拼接多个结果以满足密钥的长度:
而每个 block 则通过则通过函数F得到:
在函数 F 里,PRF会进行 c 次的运算,然后把得到的结果进行异或运算,得到最终的值。
第一次,PRF 会使用 Password 作为 key,Salt 拼接上编码成大字节序的 32 位整型的i作为盐值进行运算。
而后续的 c-1 次则会使用上次得到的结果作为盐值。
函数 F 大致的流程图如下:
notion image

set

python中集合(set)是一个无序不重复元素的集,基本功能包括关系测试和消除重复元素,还可以計算交集、差集、并集等。set有3个特点
1.确定性:集合中的元素必须是确定的。;
2.互异性:集合中的元素互不相同,如:集合A={1,a},则a不能等于1);
3.无序性:集合中的元素沒有先后之分,如:{3,4,5}和{3,5,4}算作同一個集合。
方法
描述
平均情况
最坏情况
set.add(elmnt)
为集合添加元素
O(1)
O(1)
set.update(set)
给集合添加元素
O(1)
O(1)
set.clear()
移除集合中的所有元素
O(n)
O(n)
set.remove(item)
remove() 方法在移除一个不存在的元素时会发生错误,而 discard() 方法不会。
O(1)
O(1)
set.discard(value)
删除集合中指定的元素
O(1)
O(1)
set.pop()
随机移除元素
O(1)
O(1)
set.copy()
拷贝一个集合
O(n)
O(n)
set.difference(set) s-t
返回集合的差集
O(len(s))
set.difference_update(set)
与 difference() 方法的区别在于 difference() 方法返回一个移除相同元素的新集合,而 difference_update() 方法是直接在原来的集合中移除元素,没有返回值
O(len(s))
set.intersection(set1, set2 ... etc) s&t
返回两个或更多集合中都包含的元素,即交集
O(min(len(s), len(t))
set.intersection_update(set1, set2 ... etc)
intersection() 方法是返回一个新的集合而 intersection_update() 方法是在原始的集合上移除不重叠的元素。
O(min(len(s), len(t))
O(len(s) * len(t))
set.isdisjoint(set)
判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。
set.issubset(set)
判断指定集合是否为该方法参数集合的子集。
set.issuperset(set)
判断该方法的参数集合是否为指定集合的子集
set.symmetric_difference(set)
即会移除两个集合中都存在的元素
O(len(t))
O(len(s) * len(t))
set.symmetric_difference_update(set)
symmetric_difference是否返回一个新的集合,symmetric_difference_update 返回当前集合。
O(len(t))
O(len(t) * len(s))
set.union(set1, set2...) s|t
返回两个集合的并集
O(len(s)+len(t))
x in s
x是不是在集合s中
O(1)
O(n)

原理

集合的内部结构是一张哈希表:哈希表内只存储单一的元素。
  • 插入:当向集合中插入数据时,Python会根据通过 hash(valuse) 函数,计算该元素对应的哈希值。得到哈希值(例如为 hash)之后,再结合集合要存储数据的个数(例如 n),就可以得到该元素应该插入到哈希表中的位置(比如用 取模法 hash%n 方式)。
  • 查找:在哈希表中查找数据,和插入操作类似,Python 会根据哈希值,找到该元素应该存储到哈希表中的位置,然后和该位置的元素比较元素值:
  • 删除:对于删除操作,Python 会暂时对这个位置的元素赋于一个特殊的值,等到重新调整哈希表的大小时,再将其删除。

实现

set的去重是通过两个函数__hash__和__eq__结合实现的。 1、当两个变量的哈希值不相同时,就认为这两个变量是不同的 2、当两个变量哈希值一样时,调用__eq__方法,当返回值为True时认为这两个变量是同一个,应该去除一个。返回FALSE时,不去重

dic字典

函数及描述
平均时间复杂度
最坏时间复杂度
删除字典内所有元素
O(n)
O(n)
返回一个字典的浅复制
O(n)
O(n)
dict.fromkeys(seq[, value])
创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值
O(1)
O(n)
和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
O(1)
O(n)
把字典dict2的键/值对更新到dict里
O(1)
O(n)
返回指定键的值,如果键不在字典中返回 default 设置的默认值
O(1)
O(n)
pop(key[,default])
删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
O(1)
O(n)
返回并删除字典中的最后一对键和值。
O(1)
O(n)
如果键在字典dict里返回true,否则返回false
O(1)
O(n)
以列表返回视图对象,是一个可遍历的key/value 对
O(n)
O(n)
返回一个视图对象
O(n)
O(n)
返回一个视图对象
O(n)
O(n)
 
  • 哈希
  • python的数组、栈与队列排序算法
    Loading...
    目录