无法通过模块查看或修改PYTHONHASHSEED的值

Fer*_*dox 6 python environment-variables python-3.4

尝试使用以下方法查看值PYTHONHASHSEED:

# (this is inside module_1.py)
os.environ['PYTHONHASHSEED'] 
Run Code Online (Sandbox Code Playgroud)

引发KeyError:

Traceback (most recent call last):
  File "/home/black/Dev/Projects/module_1.py", line 2, in <module>
    os.environ['PYTHONHASHSEED']
  File "/usr/lib/python3.4/os.py", line 631, in __getitem__
    raise KeyError(key) from None
KeyError: 'PYTHONHASHSEED'
Run Code Online (Sandbox Code Playgroud)

打印的内容os.environ通过

for i in sorted(os.environ):
    print(i)

# prints:
# CLUTTER_IM_MODULE
# COMPIZ_BIN_PATH
# ...
# etc.
Run Code Online (Sandbox Code Playgroud)

揭示PYTHONHASHSEED不是在内部,但我很确定它应该有一个值,因为在Python 3.3和更高版本上,默认情况下启用了哈希随机化。

问题:
为什么我不能以这种方式访问​​它的值module_1.py?如何通过它访问它?

PM *_*ing 5

您可以在 Python 脚本中设置 PYTHONHASHSEED,但它对hash()函数的行为没有影响——它需要在解释器启动之前在解释器的环境中进行设置。


如何使用纯 Python 设置其值

诀窍是将环境变量传递给子进程中的 Python 解释器。

import random
from subprocess import call

random.seed(37)
cmd = ['python', '-c', 'print(hash("abc"))']

for i in range(5):
    hashseed = bytes(random.randint(0, 4294967295))
    print('\nhashseed', hashseed)
    call(cmd, env={'PYTHONHASHSEED': hashseed})
Run Code Online (Sandbox Code Playgroud)

输出

hashseed 2929187283
-972692480

hashseed 393430205
2066796829

hashseed 2653501013
1620854360

hashseed 3616018455
-599248233

hashseed 3584366196
-2103216293
Run Code Online (Sandbox Code Playgroud)

您可以更改cmd列表,使其运行hashtest.py上面的脚本:

cmd = ['python', 'hashtest.py']
Run Code Online (Sandbox Code Playgroud)

或者如果hashtest.py是可执行的,

cmd = './hashtest.py'
Run Code Online (Sandbox Code Playgroud)

通过传递 adict作为env参数,我们替换了将传递给命令的默认环境。如果您需要访问那些其他环境变量,那么您应该os.environ在调用脚本中进行修改,例如,os.environ['PYTHONHASHSEED'] = hashseed.

如何使用 Bash 设置其值

首先,我们有一个简短的 Bash 脚本pyhashtest.bsh,它使用 RANDOM 环境变量作为 PYTHONHASHSEED 的种子。必须导出此变量,以便 Python 解释器可以看到它。然后我们运行我们的 Python 脚本hashtest.py。我们在循环中执行此操作 5 次,因此我们可以看到使用不同的种子对哈希值有影响。

Python 脚本hashtest.py从环境中读取 PYTHONHASHSEED 并打印它以表明它具有我们期望的值。然后我们计算并打印一个短字符串的哈希值。

pyhashtest.bsh

import random
from subprocess import call

random.seed(37)
cmd = ['python', '-c', 'print(hash("abc"))']

for i in range(5):
    hashseed = bytes(random.randint(0, 4294967295))
    print('\nhashseed', hashseed)
    call(cmd, env={'PYTHONHASHSEED': hashseed})
Run Code Online (Sandbox Code Playgroud)

哈希测试.py

hashseed 2929187283
-972692480

hashseed 393430205
2066796829

hashseed 2653501013
1620854360

hashseed 3616018455
-599248233

hashseed 3584366196
-2103216293
Run Code Online (Sandbox Code Playgroud)

典型输出

cmd = ['python', 'hashtest.py']
Run Code Online (Sandbox Code Playgroud)

要运行这些程序,请将它们保存到同一个目录中,例如运行 Python 脚本的常用目录。然后打开 Bash shell 并使用cd命令导航到该目录。

例如,如果你已经保存了脚本,/mnt/sda2/fred/python那么你会这样做

cd /mnt/sda2/fred/python
Run Code Online (Sandbox Code Playgroud)

接下来,pyhashtest.bsh使用以下命令使可执行文件:

chmod a+x pyhashtest.bsh
Run Code Online (Sandbox Code Playgroud)

然后运行它

./pyhashtest.bsh
Run Code Online (Sandbox Code Playgroud)