Return a string of random order bytes suitable for cryptographic use.Documentation for the pair adds:
')
This function returns a random bytes from an OS-specific randomness source. It should not be necessary for the cryptographic applications, however, it depends on the OS implementation. It will use CryptGenRandom () on the Unix-like system.
New in version 2.4.In other words, for example, under Linux, urandom reads and returns bytes from the system device / dev / urandom. Let me remind you that in this OS there are two typical entropy source devices: / dev / random and / dev / urandom. As is known , the first device is “slow” and blocking, and the second is “fast”, and contrary to popular belief, both of them are crypto-resistant sources of (pseudo-) random numbers . I’ll say right away that KDPV has nothing to do with the article and it’s not about cryptography, security,
def urandom ( n ) :So, three lines. Moreover, this is an absolutely correct implementation without errors, except for exception handling and other details in order to comply with the specification of the function of the function on the docks. And then someone's bright head offers to speed up this code. How is this possible, you ask. Having cached a file object, the bright head responds.
with open ( '/ dev / urandom' , 'rb' ) as rnd:
return rnd. read ( n )
rnd = NoneWhat problems appear with this implementation? Scripts that become demons fall on the first invocation of urandom after the death of the parent.
def urandom ( n ) :
if rnd is None :
rnd = open ( '/ dev / urandom' , 'rb' )
return rnd. read ( n )
Copy of the open file descriptors. Each file descriptor (see open (2)) as the corresponding file descriptor in the parent. I / O attributes and signal-driven I / O attributesIn other words, the file descriptors belonging to the Python file object, after the fork, are interconnected and refer to the same file. However, if in one process the file is closed, it will not be automatically closed in the other.
I recommend to close this as invalid. The daemonization code is clearly broken.Fortunately, people were able to convince the king of the opposite, and, finally, in July caching / dev / urandom was removed - more than six months passed. I draw attention to how it was done: the code does not contain a reference to the bug number, no indication of the reasons for the patch, or, in the end, just an explanatory comment. It works, and well.
No new syntax features were added in Python 3.4.Okay, well, seriously, great progress: a bunch of libraries were taken, for example, asyncio, which has already been written a lot on Habré, improved security, cleared the release of objects - not for me to talk about it. The main thing is that before the release there were people who thought that the implementation of / dev / urandom on Python is hellishly slow, and true performance can only be ensured by the good old C. In general, the function was rewritten ... and again they stepped on the same rake . And no PEP 446 helped them. The patch was released on April 24 and this time already contained abundant comments, a link to the bug and even regression tests.
import platformI had a daemon code that closed all the file descriptors. And that's because the trouble
platform . python_build ( )
( 'default' , 'Apr 11 2014 13:05:11' )
import osprints
print ( os . listdir ( '/ proc / self / fd' ) )
import random
print ( os . listdir ( '/ proc / self / fd' ) )
The experiment is not entirely clean, because os.listdir creates its descriptor in both cases under the last number. After importing the random number 3 opened. Which file does it correspond to?['0', '1', '2', '3']
['0', '1', '2', '3', '4']
print ( os . readlink ( '/ proc / self / fd / 3' ) )
/dev/urandom
Ta-dam! I always had a bad attitude to work when importing modules ... In this case, I give the ending random.py:from os import urandom as _urandomIt remains to be noted that import random do Tornado, Twisted, uuid, and a whole bunch of other libraries, standard and not very.
class Random ( _random. Random ) :
# ...
def __init__ ( self , x = None ) :
# ...
self . seed ( x )
self . gauss_next = None
def seed ( self , a = None , version = 2 ) :
# ...
if a is None :
try :
a = int . from_bytes ( _urandom ( 32 ) , 'big' )
except NotImplementedError :
# ...
Source: https://habr.com/ru/post/223981/
All Articles