3
(h                 @   sj   d dl Z d dlmZ d dlmZ d dlmZ dedfddZd	d
 Z	dd Z
dd Zdd Zdd ZdS )    N)ValidationError)range)ugettext_lazyFz!This is not a valid IPv6 address.c             C   s.  d	}d}d
}d}t | s$t|ddt| } t| } |rHt| }|rH|S | jd}x|tt|D ]l}	d||	 kr||	 jd||	< ||	 sd||	< ||	 dkr|d7 }|dkr|	}||kr|}|}q`d}d}q`W |dkr|| }
|
t|k r|dg7 }dg|||
< |dkrdg| }dj	|}|j
 S )aU  
    Cleans an IPv6 address string.

    Validity is checked by calling is_valid_ipv6_address() - if an
    invalid address is passed, ValidationError is raised.

    Replaces the longest continuous zero-sequence with "::" and
    removes leading zeroes and makes sure all hextets are lowercase.

    Args:
        ip_str: A valid IPv6 address.
        unpack_ipv4: if an IPv4-mapped address is found,
        return the plain IPv4 address (default=False).
        error_message: An error message used in the ValidationError.

    Returns:
        A compressed IPv6 address, or the same value
       r   invalid)code:.0 r   r   r   )is_valid_ipv6_addressr   _explode_shorthand_ip_string_sanitize_ipv4_mapping_unpack_ipv4splitr   lenlstripjoinlower)ip_strZunpack_ipv4error_messagebest_doublecolon_startbest_doublecolon_lendoublecolon_startdoublecolon_lenZipv4_unpackedhextetsindexbest_doublecolon_endresult r    5/tmp/pip-install-q3hcpn_q/Django/django/utils/ipv6.pyclean_ipv6_address   sJ    





r"   c             C   s   | j  jds| S | jd}d|d kr,| S dt|d dd d	t|d dd
 d	t|d dd d	t|d dd
 d	f }dj|dd }|d| 7 }|S )a?  
    Sanitize IPv4 mapping in an expanded IPv6 address.

    This converts ::ffff:0a0a:0a0a to ::ffff:10.10.10.10.
    If there is nothing to sanitize, returns an unchanged
    string.

    Args:
        ip_str: A string, the expanded IPv6 address.

    Returns:
        The sanitized output string, if applicable.
    z0000:0000:0000:0000:0000:ffff:r   r	   r   z%d.%d.%d.%d   r               r   )r   
startswithr   intr   )r   r   ipv4_addressr   r    r    r!   r   ]   s    
r   c             C   s"   | j  jdsdS | jddd S )ag  
    Unpack an IPv4 address that was mapped in a compressed IPv6 address.

    This converts 0000:0000:0000:0000:0000:ffff:10.10.10.10 to 10.10.10.10.
    If there is nothing to sanitize, returns None.

    Args:
        ip_str: A string, the expanded IPv6 address.

    Returns:
        The unpacked IPv4 address, or None if there was nothing to unpack.
    z0000:0000:0000:0000:0000:ffff:Nr   r   )r   r(   rsplit)r   r    r    r!   r      s    r   c             C   sd  ddl m} tjd}|j| s$dS d| kr0dS | jddkrBdS d| krNdS | jdrd| jd sz| jdr~| jd r~dS | jdd	krdS d| kr| jdd	kr| jd
dkrdS t| } x| j	dD ]}|jd
dkr| j	dd |ksdS y|| W n t
k
r   dS X qy(t|ddk s>t|ddkrBdS W q tk
rZ   dS X qW dS )z
    Ensure we have a valid IPv6 address.

    Args:
        ip_str: A string, the IPv6 address.

    Returns:
        A boolean, True if this is a valid IPv6 address.
    r   )validate_ipv4_addressz^[0-9a-fA-F:.]+$Fr   z::r   z:::r'   r	      r%   i  Tr   )Zdjango.core.validatorsr,   recompilematchcountr(   endswithr   r   r   r)   
ValueError)r   r,   Z
symbols_rehextetr    r    r!   r      sB    


 
r   c             C   s   t | s| S g }| jd}d| jdd kr2d}nd}t|dkrt|d jdt|d jd }|d jd}xt|| D ]}|jd qW ||d jd7 }n
| jd}g }x*|D ]"}|jd	d
t|  | j  qW dj|S )z
    Expand a shortened IPv6 address.

    Args:
        ip_str: A string, the IPv6 address.

    Returns:
        A string, the expanded IPv6 address.
    z::r	   r   r   r'      r   Z0000r
   r&   r   )_is_shorthand_ipr   r   r   appendr   r   )r   Znew_ipr4   Zfill_tosep__Zret_ipr    r    r!   r      s$    

$

"r   c             C   s2   | j ddkrdS tdd | jdD r.dS dS )zDetermine if the address is shortened.

    Args:
        ip_str: A string, the IPv6 address.

    Returns:
        A boolean, True if the address is shortened.
    z::r   Tc             s   s   | ]}t |d k V  qdS )r&   N)r   ).0xr    r    r!   	<genexpr>  s    z#_is_shorthand_ip.<locals>.<genexpr>r   F)r1   anyr   )r   r    r    r!   r6     s
    	r6   )r.   Zdjango.core.exceptionsr   Zdjango.utils.six.movesr   Zdjango.utils.translationr   _r"   r   r   r   r   r6   r    r    r    r!   <module>   s   Q%D,