原文towardsdatascience.com/the-secrets-of-python-secrets-05e00ad426a2https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/d6af884496ed2563a527255181b1b8b5.png图片由 Tayeb MEZAHDIA 在 Pixabay 提供如果你从事数据科学和分析领域的工作我猜你一定像我一样大量使用 Python 的random模块。确实当我们需要做一些模拟、数据采样和各种各样的统计算法时它非常有用。然而Python 中还有一个名为secrets的内置模块我相信它远不如random模块为人所知。它几乎与random做的事情相同。甚至有一些函数名称完全相同。为什么会有这样一个模块我们应该在什么情况下使用secrets但不使用random请跟随这篇文章以获得答案。在所有这些之前与我的其他大多数文章不同没有名为 “安装” 的部分。secrets模块是 Python 内置的。因此我们可以直接使用它无需担心安装问题。1. 安全生成随机数https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4e1bb7a78b6f3e8934fa190e7c92d775.png图片由 AndreasAux 在 Pixabay 提供让我们来看看 Secrets 模块中的一些基本随机函数。然后我会解释为什么在某些情况下我们不应该使用random。1.1 随机选择Secrets 模块中的choice()函数帮助我们从一个序列中选择一个项目例如一个列表。characters[a,b,c,d,e,f,g,h]secrets.choice(characters)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/7e8f01b4d4815d57d19f75d62762b37c.png当然如果我们再次运行该函数结果很可能是不同的或者有 1/8 的机会得到相同的结果哈哈。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/cb8719a30fbb59c2e84aaf2a6e1dd3ad.png事实上Python 中的字符串也是一个序列。因此以下在结果和概率方面是等效的。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/9a50c68c661b0f3a378bd395f69d176c.png你可能会注意到这与 “random” 模块中的choice()函数非常相似。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/a9de04ccece2ef84b7ba85b2fd47e19f.png1.2 范围内的随机整数我们可以使用randbelow()函数从一个范围内生成一个整数。在下面的示例中将在范围 0, 100) 内生成一个随机整数。换句话说一个从 0包含到 100不包含的整数。secrets.randbelow(100)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c320e7b7eb70e3ce6e32872a1f64cd4a.png请注意在函数randint(a,b)中b 是包含的。1.3 具有特定位的随机数函数randbits()帮助我们生成具有特定位的随机数。例如如果我们想要一个 16 位的数字这意味着它是 2¹⁶65,535。所以这个数字不会超过 65,535。# 2¹⁶ in decimal it means 0 - 65535secrets.randbits(16)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4ee2481d062e74418df24def056dfb7a.png当然random模块也有一个等效的功能。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/5e27c6157b8516445ea568c8fd096ea8.png现在是时候回答这个问题了2. 为什么以及何时应该使用secretshttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/dd11a697b6430295304e4b7571598ba1.png图片由 Werner Moser 在 Pixabay 提供先说缺点“secrets模块生成的随机数可能比random模块表现得更差。那么为什么我们需要使用secrets”2.1 random模块是假随机在random模块中你可能知道在我们开始生成任何随机数之前可以使用seed。请看下面的例子。random.seed(10)print(random.random())现在如果我们运行这个函数两次我们将得到两个不同的浮点数。这两个数字看起来相当随机。然而如果我们将种子重置为之前使用的相同值我们就可以得到两个相同的数字https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4c50805e1453864a9084fd7083cecc5d.png基本上种子是生成一个内部状态的标准。这个内部状态将被用来初始化一系列伪随机数生成器。想象一下有一个数字列表已经被确定程序只是逐个输出这些数字。这些数字看起来相当随机。至少对我们人类来说我们称之为随机。然而我们也可以说它是假随机或者说模拟随机。2.2 secrets模块提供真正的随机性与random模块不同secrets模块提供了真正的随机性。后者利用操作系统资源来获取真正的随机性。通常这来自硬件级别的噪声可能来自以下系统之一。热噪声 – 由于温度导体中电子的随机运动。时钟抖动 – 硬件时钟信号时间的不规则变化。内存访问时间 – 读取或写入数据到内存所需的时间这在微观层面上总是波动。因此这种硬件级别的噪声是完全不可预测和不可复制的。2.3 何时使用random或secrets目的secrets被设计用来生成加密安全的随机数。random被设计用来生成用于模拟和其他非安全场景的随机数。安全性secrets从硬件级别的噪声中生成随机数这些随机数是安全和不可预测的。random从伪随机数生成如果有人知道种子它就可以被预测这是不安全的。用例secrets可以用于生成令牌、密码和其他敏感对象。random可以用于模拟、游戏、数据分析和其他一般用途。可重现性secrets生成的对象是不可重现的。如果我们知道“种子”random生成的对象是可重现的。性能secrets在生成大量随机对象时可能会较慢。random通常更快这使得它适合生成大量对象。因此它通常用于数据分析场景。3. 样例用例https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/ead894930b929c8a4591909ba720e0aa.png图片由 Davie Bicker 提供来自 Pixabay现在让我们看看secrets模块的一些样例用例。3.1 生成复杂密码如果你曾经使用过像 LastPass 这样的密码管理软件或者甚至是 Chrome 浏览器本身这些工具可以为我们生成一个随机的安全密码。例如在一个场景中我们需要生成一个安全的密码它必须包含数字和字母至少 8 个字符长度至少包含一个小写字母、一个大写字母和一个数字。函数可以写成以下形式。它首先需要确保长度大于 8如果不是将会引发错误。iflength8:raiseValueError(Password length must be at least 8 characters)然后让我们将一个小写字母、一个大写字母和一个数字放入字符列表中。如果你担心这些必需的字符在特定位置请暂时放下你的疑问。我们稍后会解决它。password[secrets.choice(string.ascii_lowercase),secrets.choice(string.ascii_uppercase),secrets.choice(string.digits)]然后让我们定义一个所有可以作为生成密码候选字符的字符的超集。alphabetstring.ascii_lettersstring.digits然后让我们从这个候选集中随机选择字符以组成密码的其余长度。请注意我们已经有 3 个字符了所以我们只需要选择length - 3个字符。password[secrets.choice(alphabet)for_inrange(length-3)]现在最重要的步骤是在输出之前对这些字符进行洗牌。这是为了保证所有字符的位置都是随机的。secrets.SystemRandom().shuffle(password)最后我们可以将所有字符连接成一个字符串并返回它。return.join(password)为了你的方便这个函数的代码如下。importstringimportsecretsdefgenerate_secure_password(length):iflength8:raiseValueError(Password length must be at least 8 characters)# Ensure at least one lowercase, one uppercase, and one digitpassword[secrets.choice(string.ascii_lowercase),secrets.choice(string.ascii_uppercase),secrets.choice(string.digits)]# Define character setsalphabetstring.ascii_lettersstring.digits# Add more characters to meet the required lengthpassword[secrets.choice(alphabet)for_inrange(length-3)]# Shuffle the list to ensure randomnesssecrets.SystemRandom().shuffle(password)return.join(password)# Example usage:print(generate_secure_password(8))https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/d8843a09e460f13565af86b75f673a1e.png如果我们需要一个更长的密码比如 30 个字符它也能很好地完成这项任务。print(generate_secure_password(30))https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4248de4734a6563aa44a5925ea83f65a.png3.2 生成 URL 安全的令牌另一个典型的用例是生成一个 URL 安全的令牌。它是 URL 安全的因此可以直接在 URL 中使用支持的字符。换句话说令牌保证可以放入地址字段并且不需要 URL 编码。urlhttps://example.com/tokensecrets.token_urlsafe(32)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/1b1c94fc4dbd6908de1ae98ae6f3f758.png摘要https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/55393b4ecd8bf5cdf83e401359e0d9b4.png图片由Luisella Planeta LOVE PEACE .com/users/sweetlouise-3967705/?utm_sourcelink-attributionutm_mediumreferralutm_campaignimageutm_content2227857)来自 Pixabay 提供在本文中我介绍了 Python 内置的secrets模块。它可以提供密码学安全的随机数、选择和其他我们在编程中需要的随机性。我认为主要的要点应该是伪随机数和密码学安全随机数之间的区别。前者的代表是random模块而secrets则是后者。我们应该理解random提供更好的、更快的和可重复的随机性而secrets提供安全和不可预测的随机性可用于密码和安全令牌生成。希望这能帮到您
你不知道的 Python Secrets
原文towardsdatascience.com/the-secrets-of-python-secrets-05e00ad426a2https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/d6af884496ed2563a527255181b1b8b5.png图片由 Tayeb MEZAHDIA 在 Pixabay 提供如果你从事数据科学和分析领域的工作我猜你一定像我一样大量使用 Python 的random模块。确实当我们需要做一些模拟、数据采样和各种各样的统计算法时它非常有用。然而Python 中还有一个名为secrets的内置模块我相信它远不如random模块为人所知。它几乎与random做的事情相同。甚至有一些函数名称完全相同。为什么会有这样一个模块我们应该在什么情况下使用secrets但不使用random请跟随这篇文章以获得答案。在所有这些之前与我的其他大多数文章不同没有名为 “安装” 的部分。secrets模块是 Python 内置的。因此我们可以直接使用它无需担心安装问题。1. 安全生成随机数https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4e1bb7a78b6f3e8934fa190e7c92d775.png图片由 AndreasAux 在 Pixabay 提供让我们来看看 Secrets 模块中的一些基本随机函数。然后我会解释为什么在某些情况下我们不应该使用random。1.1 随机选择Secrets 模块中的choice()函数帮助我们从一个序列中选择一个项目例如一个列表。characters[a,b,c,d,e,f,g,h]secrets.choice(characters)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/7e8f01b4d4815d57d19f75d62762b37c.png当然如果我们再次运行该函数结果很可能是不同的或者有 1/8 的机会得到相同的结果哈哈。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/cb8719a30fbb59c2e84aaf2a6e1dd3ad.png事实上Python 中的字符串也是一个序列。因此以下在结果和概率方面是等效的。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/9a50c68c661b0f3a378bd395f69d176c.png你可能会注意到这与 “random” 模块中的choice()函数非常相似。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/a9de04ccece2ef84b7ba85b2fd47e19f.png1.2 范围内的随机整数我们可以使用randbelow()函数从一个范围内生成一个整数。在下面的示例中将在范围 0, 100) 内生成一个随机整数。换句话说一个从 0包含到 100不包含的整数。secrets.randbelow(100)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c320e7b7eb70e3ce6e32872a1f64cd4a.png请注意在函数randint(a,b)中b 是包含的。1.3 具有特定位的随机数函数randbits()帮助我们生成具有特定位的随机数。例如如果我们想要一个 16 位的数字这意味着它是 2¹⁶65,535。所以这个数字不会超过 65,535。# 2¹⁶ in decimal it means 0 - 65535secrets.randbits(16)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4ee2481d062e74418df24def056dfb7a.png当然random模块也有一个等效的功能。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/5e27c6157b8516445ea568c8fd096ea8.png现在是时候回答这个问题了2. 为什么以及何时应该使用secretshttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/dd11a697b6430295304e4b7571598ba1.png图片由 Werner Moser 在 Pixabay 提供先说缺点“secrets模块生成的随机数可能比random模块表现得更差。那么为什么我们需要使用secrets”2.1 random模块是假随机在random模块中你可能知道在我们开始生成任何随机数之前可以使用seed。请看下面的例子。random.seed(10)print(random.random())现在如果我们运行这个函数两次我们将得到两个不同的浮点数。这两个数字看起来相当随机。然而如果我们将种子重置为之前使用的相同值我们就可以得到两个相同的数字https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4c50805e1453864a9084fd7083cecc5d.png基本上种子是生成一个内部状态的标准。这个内部状态将被用来初始化一系列伪随机数生成器。想象一下有一个数字列表已经被确定程序只是逐个输出这些数字。这些数字看起来相当随机。至少对我们人类来说我们称之为随机。然而我们也可以说它是假随机或者说模拟随机。2.2 secrets模块提供真正的随机性与random模块不同secrets模块提供了真正的随机性。后者利用操作系统资源来获取真正的随机性。通常这来自硬件级别的噪声可能来自以下系统之一。热噪声 – 由于温度导体中电子的随机运动。时钟抖动 – 硬件时钟信号时间的不规则变化。内存访问时间 – 读取或写入数据到内存所需的时间这在微观层面上总是波动。因此这种硬件级别的噪声是完全不可预测和不可复制的。2.3 何时使用random或secrets目的secrets被设计用来生成加密安全的随机数。random被设计用来生成用于模拟和其他非安全场景的随机数。安全性secrets从硬件级别的噪声中生成随机数这些随机数是安全和不可预测的。random从伪随机数生成如果有人知道种子它就可以被预测这是不安全的。用例secrets可以用于生成令牌、密码和其他敏感对象。random可以用于模拟、游戏、数据分析和其他一般用途。可重现性secrets生成的对象是不可重现的。如果我们知道“种子”random生成的对象是可重现的。性能secrets在生成大量随机对象时可能会较慢。random通常更快这使得它适合生成大量对象。因此它通常用于数据分析场景。3. 样例用例https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/ead894930b929c8a4591909ba720e0aa.png图片由 Davie Bicker 提供来自 Pixabay现在让我们看看secrets模块的一些样例用例。3.1 生成复杂密码如果你曾经使用过像 LastPass 这样的密码管理软件或者甚至是 Chrome 浏览器本身这些工具可以为我们生成一个随机的安全密码。例如在一个场景中我们需要生成一个安全的密码它必须包含数字和字母至少 8 个字符长度至少包含一个小写字母、一个大写字母和一个数字。函数可以写成以下形式。它首先需要确保长度大于 8如果不是将会引发错误。iflength8:raiseValueError(Password length must be at least 8 characters)然后让我们将一个小写字母、一个大写字母和一个数字放入字符列表中。如果你担心这些必需的字符在特定位置请暂时放下你的疑问。我们稍后会解决它。password[secrets.choice(string.ascii_lowercase),secrets.choice(string.ascii_uppercase),secrets.choice(string.digits)]然后让我们定义一个所有可以作为生成密码候选字符的字符的超集。alphabetstring.ascii_lettersstring.digits然后让我们从这个候选集中随机选择字符以组成密码的其余长度。请注意我们已经有 3 个字符了所以我们只需要选择length - 3个字符。password[secrets.choice(alphabet)for_inrange(length-3)]现在最重要的步骤是在输出之前对这些字符进行洗牌。这是为了保证所有字符的位置都是随机的。secrets.SystemRandom().shuffle(password)最后我们可以将所有字符连接成一个字符串并返回它。return.join(password)为了你的方便这个函数的代码如下。importstringimportsecretsdefgenerate_secure_password(length):iflength8:raiseValueError(Password length must be at least 8 characters)# Ensure at least one lowercase, one uppercase, and one digitpassword[secrets.choice(string.ascii_lowercase),secrets.choice(string.ascii_uppercase),secrets.choice(string.digits)]# Define character setsalphabetstring.ascii_lettersstring.digits# Add more characters to meet the required lengthpassword[secrets.choice(alphabet)for_inrange(length-3)]# Shuffle the list to ensure randomnesssecrets.SystemRandom().shuffle(password)return.join(password)# Example usage:print(generate_secure_password(8))https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/d8843a09e460f13565af86b75f673a1e.png如果我们需要一个更长的密码比如 30 个字符它也能很好地完成这项任务。print(generate_secure_password(30))https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/4248de4734a6563aa44a5925ea83f65a.png3.2 生成 URL 安全的令牌另一个典型的用例是生成一个 URL 安全的令牌。它是 URL 安全的因此可以直接在 URL 中使用支持的字符。换句话说令牌保证可以放入地址字段并且不需要 URL 编码。urlhttps://example.com/tokensecrets.token_urlsafe(32)https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/1b1c94fc4dbd6908de1ae98ae6f3f758.png摘要https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/55393b4ecd8bf5cdf83e401359e0d9b4.png图片由Luisella Planeta LOVE PEACE .com/users/sweetlouise-3967705/?utm_sourcelink-attributionutm_mediumreferralutm_campaignimageutm_content2227857)来自 Pixabay 提供在本文中我介绍了 Python 内置的secrets模块。它可以提供密码学安全的随机数、选择和其他我们在编程中需要的随机性。我认为主要的要点应该是伪随机数和密码学安全随机数之间的区别。前者的代表是random模块而secrets则是后者。我们应该理解random提供更好的、更快的和可重复的随机性而secrets提供安全和不可预测的随机性可用于密码和安全令牌生成。希望这能帮到您