| |
|
|
| """Serial Number Arthimetic from RFC 1982""" |
|
|
|
|
| class Serial: |
| def __init__(self, value: int, bits: int = 32): |
| self.value = value % 2**bits |
| self.bits = bits |
|
|
| def __repr__(self): |
| return f"dns.serial.Serial({self.value}, {self.bits})" |
|
|
| def __eq__(self, other): |
| if isinstance(other, int): |
| other = Serial(other, self.bits) |
| elif not isinstance(other, Serial) or other.bits != self.bits: |
| return NotImplemented |
| return self.value == other.value |
|
|
| def __ne__(self, other): |
| if isinstance(other, int): |
| other = Serial(other, self.bits) |
| elif not isinstance(other, Serial) or other.bits != self.bits: |
| return NotImplemented |
| return self.value != other.value |
|
|
| def __lt__(self, other): |
| if isinstance(other, int): |
| other = Serial(other, self.bits) |
| elif not isinstance(other, Serial) or other.bits != self.bits: |
| return NotImplemented |
| if self.value < other.value and other.value - self.value < 2 ** (self.bits - 1): |
| return True |
| elif self.value > other.value and self.value - other.value > 2 ** ( |
| self.bits - 1 |
| ): |
| return True |
| else: |
| return False |
|
|
| def __le__(self, other): |
| return self == other or self < other |
|
|
| def __gt__(self, other): |
| if isinstance(other, int): |
| other = Serial(other, self.bits) |
| elif not isinstance(other, Serial) or other.bits != self.bits: |
| return NotImplemented |
| if self.value < other.value and other.value - self.value > 2 ** (self.bits - 1): |
| return True |
| elif self.value > other.value and self.value - other.value < 2 ** ( |
| self.bits - 1 |
| ): |
| return True |
| else: |
| return False |
|
|
| def __ge__(self, other): |
| return self == other or self > other |
|
|
| def __add__(self, other): |
| v = self.value |
| if isinstance(other, Serial): |
| delta = other.value |
| elif isinstance(other, int): |
| delta = other |
| else: |
| raise ValueError |
| if abs(delta) > (2 ** (self.bits - 1) - 1): |
| raise ValueError |
| v += delta |
| v = v % 2**self.bits |
| return Serial(v, self.bits) |
|
|
| def __iadd__(self, other): |
| v = self.value |
| if isinstance(other, Serial): |
| delta = other.value |
| elif isinstance(other, int): |
| delta = other |
| else: |
| raise ValueError |
| if abs(delta) > (2 ** (self.bits - 1) - 1): |
| raise ValueError |
| v += delta |
| v = v % 2**self.bits |
| self.value = v |
| return self |
|
|
| def __sub__(self, other): |
| v = self.value |
| if isinstance(other, Serial): |
| delta = other.value |
| elif isinstance(other, int): |
| delta = other |
| else: |
| raise ValueError |
| if abs(delta) > (2 ** (self.bits - 1) - 1): |
| raise ValueError |
| v -= delta |
| v = v % 2**self.bits |
| return Serial(v, self.bits) |
|
|
| def __isub__(self, other): |
| v = self.value |
| if isinstance(other, Serial): |
| delta = other.value |
| elif isinstance(other, int): |
| delta = other |
| else: |
| raise ValueError |
| if abs(delta) > (2 ** (self.bits - 1) - 1): |
| raise ValueError |
| v -= delta |
| v = v % 2**self.bits |
| self.value = v |
| return self |
|
|