You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.5 KiB
118 lines
3.5 KiB
# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license |
|
|
|
"""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
|
|
|