Implements the interface ID generation algorithm described in RFC 3041.
    The function takes the Modified EUI-64 interface identifier generated
    as described in RFC 4291 and an optional previous history value (the
    first element of the output of this function). If no previous interface
    identifier is provided, a random one is generated. The function returns
    a tuple containing the randomized interface identifier and the history
    value (for possible future use). Input and output values are provided in
    a "printable" format as depicted below.

    ex:
    >>> in6_getRandomizedIfaceId('20b:93ff:feeb:2d3')
    ('4c61:76ff:f46a:a5f3', 'd006:d540:db11:b092')
    >>> in6_getRandomizedIfaceId('20b:93ff:feeb:2d3',
                                 previous='d006:d540:db11:b092')
    ('fe97:46fe:9871:bd38', 'eeed:d79c:2e3f:62e')

def in6_getRandomizedIfaceId(ifaceid, previous=None):
    """
    Implements the interface ID generation algorithm described in RFC 3041.
    The function takes the Modified EUI-64 interface identifier generated
    as described in RFC 4291 and an optional previous history value (the
    first element of the output of this function). If no previous interface
    identifier is provided, a random one is generated. The function returns
    a tuple containing the randomized interface identifier and the history
    value (for possible future use). Input and output values are provided in
    a "printable" format as depicted below.

    ex:
    >>> in6_getRandomizedIfaceId('20b:93ff:feeb:2d3')
    ('4c61:76ff:f46a:a5f3', 'd006:d540:db11:b092')
    >>> in6_getRandomizedIfaceId('20b:93ff:feeb:2d3',
                                 previous='d006:d540:db11:b092')
    ('fe97:46fe:9871:bd38', 'eeed:d79c:2e3f:62e')
    """

    s = b""
    if previous is None:
        d = b"".join(chb(x) for x in range(256))
        for _ in range(8):
            s += chb(random.choice(d))
        previous = s
    s = inet_pton(socket.AF_INET6, "::" + ifaceid)[8:] + previous
    import hashlib
    s = hashlib.md5(s).digest()
    s1, s2 = s[:8], s[8:]
    s1 = chb(orb(s1[0]) | 0x04) + s1[1:]
    s1 = inet_ntop(socket.AF_INET6, b"\xff" * 8 + s1)[20:]
    s2 = inet_ntop(socket.AF_INET6, b"\xff" * 8 + s2)[20:]
    return (s1, s2)