B
    ë?[s  ã               @   s¨   d Z dZdddddddgZd	d
lmZ d	dlZejd	 dkrRejd dkrRd	dlT G dd„ deƒZ	e	ƒ Z
e
jZe
jZe
jZe
jZe
jZe
jZd	dlmZmZmZmZ dS )zHA cryptographically strong version of Python's standard "random" module.z$Id$ÚStrongRandomÚgetrandbitsÚ	randrangeÚrandintÚchoiceÚshuffleÚsampleé    )ÚRandomNé   é   )Ú*c               @   sF   e Zd Zddd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Z	dS )r   Nc             C   sV   |d kr|d krd | _ n:|d k	r0|d kr0|| _ n"|d krJ|d k	rJ|j| _ ntdƒ‚d S )Nz(Cannot specify both 'rng' and 'randfunc')Ú	_randfuncÚreadÚ
ValueError)ÚselfÚrngZrandfunc© r   ú3lib/python3.7/site-packages/Crypto/Random/random.pyÚ__init__$   s    
zStrongRandom.__init__c             C   s:   | j dkrt ¡ j| _ d|> d }|t|   t|dƒ¡ƒ@ S )z0Return a python long integer with k random bits.Nr   é   )r   r	   Únewr   Úbytes_to_longÚceil_div)r   ÚkÚmaskr   r   r   r   .   s    
zStrongRandom.getrandbitsc             G   sö   t |ƒdkr|\}}}nHt |ƒdkr2|\}}d}n.t |ƒdkrN|\}d}d}ntdt |ƒf ƒ‚t|tƒr~t|tƒr~t|tƒs†tdƒ‚|dkr–tdƒ‚t|| |ƒ}|dk r°d}|dk rÊtd|||f ƒ‚|}x||krè|  t|ƒ¡}qÐW |||  S )	zkrandrange([start,] stop[, step]):
        Return a randomly-selected element from range(start, stop, step).é   r
   r   r   z.randrange expected at most 3 arguments, got %dz$randrange requires integer argumentsz(randrange step argument must not be zeroz%empty range for randrange(%r, %r, %r))ÚlenÚ	TypeErrorÚ
isinstanceÚintr   r   r   Úsize)r   ÚargsÚstartÚstopÚstepÚnum_choicesÚrr   r   r   r   5   s2    



zStrongRandom.randrangec             C   sJ   t |tƒrt |tƒstdƒ‚|  ||d ¡}||  kr@|ksFn t‚|S )z0Return a random integer N such that a <= N <= b.z"randint requires integer argumentsr   )r   r   r   r   ÚAssertionError)r   ÚaÚbÚNr   r   r   r   W   s
    zStrongRandom.randintc             C   s&   t |ƒdkrtdƒ‚||  t |ƒ¡ S )zrReturn a random element from a (non-empty) sequence.

        If the seqence is empty, raises IndexError.
        r   zempty sequence)r   Ú
IndexErrorr   )r   Úseqr   r   r   r   _   s    zStrongRandom.choicec             C   s:   t |ƒ}x,tt|ƒƒD ]}| |  t|ƒ¡¡||< qW dS )zShuffle the sequence in place.N)ÚlistÚranger   Úpopr   )r   ÚxÚitemsÚir   r   r   r   h   s    zStrongRandom.shufflec             C   sp   t |ƒ}||krtdƒ‚g }i }xJt|ƒD ]>}d}x|dksD||krP|  |¡}q4W | || ¡ d||< q*W |S )zNReturn a k-length list of unique elements chosen from the population sequence.zsample larger than populationNr   )r   r   r.   r   Úappend)r   Z
populationr   r%   ZretvalZselectedr2   r&   r   r   r   r   r   s    zStrongRandom.sample)NN)
Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r   r   r   r   r   r   #   s   

"	
)r   r   Úlong_to_bytesr    )Ú__doc__Z__revision__Ú__all__ZCryptor	   ÚsysÚversion_infoZCrypto.Util.py21compatÚobjectr   Z_rr   r   r   r   r   r   ZCrypto.Util.numberr   r   r7   r    r   r   r   r   Ú<module>   s   `