【问题标题】:How to implement a os.urandom function - Python2如何实现 os.urandom 函数 - Python2
【发布时间】:2021-07-28 22:23:43
【问题描述】:

我正在实现一个函数来替换os.urandom(n)。下面的代码是我目前所拥有的:

def random_entropy(n):
    """
    Returns a random entropy, which is a sequence of numbers between 0, 255

    :n: a integer number
    """
    if n <= 0:
        return ""
    buffer = []
    for i in range(0, n):
        number = random.randint(0, 255)
        buffer.append(hex(number))
    
    return ''.join(buffer)

如果我去终端,我会得到以下输出:

>>> import os
>>> os.urandom(10)
'm\xd4\x94\x00x7\xbe\x04\xa2R'
>>> type(os.urandom(10))
<type 'str'>
>>> map(ord, os.urandom(10))
[65, 120, 218, 135, 66, 134, 141, 140, 178, 25]

最后,我希望我的函数返回与os.urandom 类似的输出:'m\xd4\x94\x00x7\xbe\x04\xa2R'(我的意思是二进制输出)。我怎样才能做到这一点?我正在为 SGX 的 ecdsa 模块实现这个,所以我不能使用 ossecrets 包。

来自 Python 文档:

返回适合加密使用的大小随机字节字符串。

【问题讨论】:

标签: python python-2.7 random binary


【解决方案1】:

首先,在开始之前,您应该知道random 在许多应用程序中不足以替代urandom。阅读问题 cmets 中给出的链接。您在函数名称中滥用“熵”一词。

通过在每个数字上使用hex,您可以将其转换为可读的多字符字符串表示形式。你不想要那个,你想要chr

以下是 Python 2 代码的快速修复:

def random_entropy(n):
    """
    Returns a random entropy, which is a sequence of numbers between 0, 255

    :n: a integer number
    """
    if n <= 0:
        return ""
    buffer = []
    for i in range(0, n):
        number = random.randint(0, 255)
        buffer.append(chr(number))
    
    return ''.join(buffer)

不用先生成列表,直接在join里面放个循环就可以了,大大简化了:

def random_entropy(n):
    """
    Returns a random entropy, which is a sequence of numbers between 0, 255

    :n: a integer number
    """
    return ''.join(chr(random.randint(0, 255)) for _ in range(n))

Python 3 做的事情有点不同。这是等效的:

def random_entropy(n):
    """
    Returns a random entropy, which is a sequence of numbers between 0, 255

    :n: a integer number
    """
    return b''.join(random.randint(0, 255).to_bytes(1, 'little') for _ in range(n))

编辑:最后,在 Python 3.9 中,random 中有一个函数可以完全满足您的要求:random.randbytes。注意那里给出的警告:

此方法不应用于生成安全令牌。采用 secrets.token_bytes() 代替。

def random_bytes(n):
    """
    Returns a random byte string, which is a sequence of numbers between 0, 255.
    This should not be used in any application requiring cryptographic security.

    :n: a integer number for the number of bytes requested.
    """
    return random.randbytes(n)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-29
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多