mirror of
https://git.photon.obnh.io/AXSY/whois.git
synced 2026-03-13 02:01:32 +00:00
Initial commit: mwhois with SCION AS support and decimal AS conversion
Based on mwhois by Antonios A. Chariton Modifications for SCION AS support by Olaf Baumert, Axpo Systems AG
This commit is contained in:
273
netaddr/strategy/__init__.py
Normal file
273
netaddr/strategy/__init__.py
Normal file
@@ -0,0 +1,273 @@
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (c) 2008-2015, David P. D. Moss. All rights reserved.
|
||||
#
|
||||
# Released under the BSD license. See the LICENSE file for details.
|
||||
#-----------------------------------------------------------------------------
|
||||
"""
|
||||
Shared logic for various address types.
|
||||
"""
|
||||
import re as _re
|
||||
|
||||
from netaddr.compat import _range, _is_str
|
||||
|
||||
|
||||
def bytes_to_bits():
|
||||
"""
|
||||
:return: A 256 element list containing 8-bit binary digit strings. The
|
||||
list index value is equivalent to its bit string value.
|
||||
"""
|
||||
lookup = []
|
||||
bits_per_byte = _range(7, -1, -1)
|
||||
for num in range(256):
|
||||
bits = 8 * [None]
|
||||
for i in bits_per_byte:
|
||||
bits[i] = '01'[num & 1]
|
||||
num >>= 1
|
||||
lookup.append(''.join(bits))
|
||||
return lookup
|
||||
|
||||
#: A lookup table of 8-bit integer values to their binary digit bit strings.
|
||||
BYTES_TO_BITS = bytes_to_bits()
|
||||
|
||||
|
||||
def valid_words(words, word_size, num_words):
|
||||
"""
|
||||
:param words: A sequence of unsigned integer word values.
|
||||
|
||||
:param word_size: Width (in bits) of each unsigned integer word value.
|
||||
|
||||
:param num_words: Number of unsigned integer words expected.
|
||||
|
||||
:return: ``True`` if word sequence is valid for this address type,
|
||||
``False`` otherwise.
|
||||
"""
|
||||
if not hasattr(words, '__iter__'):
|
||||
return False
|
||||
|
||||
if len(words) != num_words:
|
||||
return False
|
||||
|
||||
max_word = 2 ** word_size - 1
|
||||
|
||||
for i in words:
|
||||
if not 0 <= i <= max_word:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def int_to_words(int_val, word_size, num_words):
|
||||
"""
|
||||
:param int_val: Unsigned integer to be divided into words of equal size.
|
||||
|
||||
:param word_size: Width (in bits) of each unsigned integer word value.
|
||||
|
||||
:param num_words: Number of unsigned integer words expected.
|
||||
|
||||
:return: A tuple contain unsigned integer word values split according
|
||||
to provided arguments.
|
||||
"""
|
||||
max_int = 2 ** (num_words * word_size) - 1
|
||||
|
||||
if not 0 <= int_val <= max_int:
|
||||
raise IndexError('integer out of bounds: %r!' % hex(int_val))
|
||||
|
||||
max_word = 2 ** word_size - 1
|
||||
|
||||
words = []
|
||||
for _ in range(num_words):
|
||||
word = int_val & max_word
|
||||
words.append(int(word))
|
||||
int_val >>= word_size
|
||||
|
||||
return tuple(reversed(words))
|
||||
|
||||
|
||||
def words_to_int(words, word_size, num_words):
|
||||
"""
|
||||
:param words: A sequence of unsigned integer word values.
|
||||
|
||||
:param word_size: Width (in bits) of each unsigned integer word value.
|
||||
|
||||
:param num_words: Number of unsigned integer words expected.
|
||||
|
||||
:return: An unsigned integer that is equivalent to value represented
|
||||
by word sequence.
|
||||
"""
|
||||
if not valid_words(words, word_size, num_words):
|
||||
raise ValueError('invalid integer word sequence: %r!' % words)
|
||||
|
||||
int_val = 0
|
||||
for i, num in enumerate(reversed(words)):
|
||||
word = num
|
||||
word = word << word_size * i
|
||||
int_val = int_val | word
|
||||
|
||||
return int_val
|
||||
|
||||
|
||||
def valid_bits(bits, width, word_sep=''):
|
||||
"""
|
||||
:param bits: A network address in a delimited binary string format.
|
||||
|
||||
:param width: Maximum width (in bits) of a network address (excluding
|
||||
delimiters).
|
||||
|
||||
:param word_sep: (optional) character or string used to delimit word
|
||||
groups (default: '', no separator).
|
||||
|
||||
:return: ``True`` if network address is valid, ``False`` otherwise.
|
||||
"""
|
||||
if not _is_str(bits):
|
||||
return False
|
||||
|
||||
if word_sep != '':
|
||||
bits = bits.replace(word_sep, '')
|
||||
|
||||
if len(bits) != width:
|
||||
return False
|
||||
|
||||
max_int = 2 ** width - 1
|
||||
|
||||
try:
|
||||
if 0 <= int(bits, 2) <= max_int:
|
||||
return True
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def bits_to_int(bits, width, word_sep=''):
|
||||
"""
|
||||
:param bits: A network address in a delimited binary string format.
|
||||
|
||||
:param width: Maximum width (in bits) of a network address (excluding
|
||||
delimiters).
|
||||
|
||||
:param word_sep: (optional) character or string used to delimit word
|
||||
groups (default: '', no separator).
|
||||
|
||||
:return: An unsigned integer that is equivalent to value represented
|
||||
by network address in readable binary form.
|
||||
"""
|
||||
if not valid_bits(bits, width, word_sep):
|
||||
raise ValueError('invalid readable binary string: %r!' % bits)
|
||||
|
||||
if word_sep != '':
|
||||
bits = bits.replace(word_sep, '')
|
||||
|
||||
return int(bits, 2)
|
||||
|
||||
|
||||
def int_to_bits(int_val, word_size, num_words, word_sep=''):
|
||||
"""
|
||||
:param int_val: An unsigned integer.
|
||||
|
||||
:param word_size: Width (in bits) of each unsigned integer word value.
|
||||
|
||||
:param num_words: Number of unsigned integer words expected.
|
||||
|
||||
:param word_sep: (optional) character or string used to delimit word
|
||||
groups (default: '', no separator).
|
||||
|
||||
:return: A network address in a delimited binary string format that is
|
||||
equivalent in value to unsigned integer.
|
||||
"""
|
||||
bit_words = []
|
||||
|
||||
for word in int_to_words(int_val, word_size, num_words):
|
||||
bits = []
|
||||
while word:
|
||||
bits.append(BYTES_TO_BITS[word & 255])
|
||||
word >>= 8
|
||||
bits.reverse()
|
||||
bit_str = ''.join(bits) or '0' * word_size
|
||||
bits = ('0' * word_size + bit_str)[-word_size:]
|
||||
bit_words.append(bits)
|
||||
|
||||
if word_sep is not '':
|
||||
# Check custom separator.
|
||||
if not _is_str(word_sep):
|
||||
raise ValueError('word separator is not a string: %r!' % word_sep)
|
||||
|
||||
return word_sep.join(bit_words)
|
||||
|
||||
|
||||
def valid_bin(bin_val, width):
|
||||
"""
|
||||
:param bin_val: A network address in Python's binary representation format
|
||||
('0bxxx').
|
||||
|
||||
:param width: Maximum width (in bits) of a network address (excluding
|
||||
delimiters).
|
||||
|
||||
:return: ``True`` if network address is valid, ``False`` otherwise.
|
||||
"""
|
||||
if not _is_str(bin_val):
|
||||
return False
|
||||
|
||||
if not bin_val.startswith('0b'):
|
||||
return False
|
||||
|
||||
bin_val = bin_val.replace('0b', '')
|
||||
|
||||
if len(bin_val) > width:
|
||||
return False
|
||||
|
||||
max_int = 2 ** width - 1
|
||||
|
||||
try:
|
||||
if 0 <= int(bin_val, 2) <= max_int:
|
||||
return True
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def int_to_bin(int_val, width):
|
||||
"""
|
||||
:param int_val: An unsigned integer.
|
||||
|
||||
:param width: Maximum allowed width (in bits) of a unsigned integer.
|
||||
|
||||
:return: Equivalent string value in Python's binary representation format
|
||||
('0bxxx').
|
||||
"""
|
||||
bin_tokens = []
|
||||
|
||||
try:
|
||||
# Python 2.6.x and upwards.
|
||||
bin_val = bin(int_val)
|
||||
except NameError:
|
||||
# Python 2.4.x and 2.5.x
|
||||
i = int_val
|
||||
while i > 0:
|
||||
word = i & 0xff
|
||||
bin_tokens.append(BYTES_TO_BITS[word])
|
||||
i >>= 8
|
||||
|
||||
bin_tokens.reverse()
|
||||
bin_val = '0b' + _re.sub(r'^[0]+([01]+)$', r'\1', ''.join(bin_tokens))
|
||||
|
||||
if len(bin_val[2:]) > width:
|
||||
raise IndexError('binary string out of bounds: %s!' % bin_val)
|
||||
|
||||
return bin_val
|
||||
|
||||
|
||||
def bin_to_int(bin_val, width):
|
||||
"""
|
||||
:param bin_val: A string containing an unsigned integer in Python's binary
|
||||
representation format ('0bxxx').
|
||||
|
||||
:param width: Maximum allowed width (in bits) of a unsigned integer.
|
||||
|
||||
:return: An unsigned integer that is equivalent to value represented
|
||||
by Python binary string format.
|
||||
"""
|
||||
if not valid_bin(bin_val, width):
|
||||
raise ValueError('not a valid Python binary string: %r!' % bin_val)
|
||||
|
||||
return int(bin_val.replace('0b', ''), 2)
|
||||
Reference in New Issue
Block a user