File: rfc1924.py

package info (click to toggle)
python-netaddr 1.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,912 kB
  • sloc: xml: 8,264; python: 6,697; makefile: 198; sh: 5
file content (84 lines) | stat: -rw-r--r-- 1,905 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# -----------------------------------------------------------------------------
#   Copyright (c) 2008 by David P. D. Moss. All rights reserved.
#
#   Released under the BSD license. See the LICENSE file for details.
# -----------------------------------------------------------------------------
"""A basic implementation of RFC 1924 ;-)"""

from netaddr.core import AddrFormatError
from netaddr.ip import IPAddress


def chr_range(low, high):
    """Returns all characters between low and high chars."""
    return [chr(i) for i in range(ord(low), ord(high) + 1)]


#: Base 85 integer index to character lookup table.
BASE_85 = (
    chr_range('0', '9')
    + chr_range('A', 'Z')
    + chr_range('a', 'z')
    + [
        '!',
        '#',
        '$',
        '%',
        '&',
        '(',
        ')',
        '*',
        '+',
        '-',
        ';',
        '<',
        '=',
        '>',
        '?',
        '@',
        '^',
        '_',
        '`',
        '{',
        '|',
        '}',
        '~',
    ]
)

#: Base 85 digit to integer lookup table.
BASE_85_DICT = dict(zip(BASE_85, range(0, 86)))


def ipv6_to_base85(addr):
    """Convert a regular IPv6 address to base 85."""
    ip = IPAddress(addr)
    int_val = int(ip)

    remainder = []
    while int_val > 0:
        remainder.append(int_val % 85)
        int_val //= 85

    encoded = ''.join([BASE_85[w] for w in reversed(remainder)])
    leading_zeroes = (20 - len(encoded)) * '0'
    return leading_zeroes + encoded


def base85_to_ipv6(addr):
    """
    Convert a base 85 IPv6 address to its hexadecimal format.
    """
    tokens = list(addr)

    if len(tokens) != 20:
        raise AddrFormatError('Invalid base 85 IPv6 address: %r' % (addr,))

    result = 0
    for i, num in enumerate(reversed(tokens)):
        num = BASE_85_DICT[num]
        result += num * 85**i

    ip = IPAddress(result, 6)

    return str(ip)