doorcontrol: Fix Credential odd parity calculation
whoops!
This commit is contained in:
parent
bde7828865
commit
ee48d286c2
@ -25,15 +25,23 @@ class InvalidParity(InvalidHexCode):
|
|||||||
class Credential:
|
class Credential:
|
||||||
bits: bitstring.Bits
|
bits: bitstring.Bits
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def even_parity(bits: bitstring.Bits) -> bool:
|
||||||
|
return bool(bits[7:19].count(1) % 2)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def odd_parity(bits: bitstring.Bits) -> bool:
|
||||||
|
return (bits[19:31].count(1) % 2) == 0
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_code(cls, facility=int, card_number=int) -> "Credential":
|
def from_code(cls, facility: int, card_number: int) -> "Credential":
|
||||||
bits = bitstring.pack(
|
bits = bitstring.pack(
|
||||||
"0b000000, 0b0, uint:8=facility, uint:16=card_number, 0b0",
|
"0b000000, 0b0, uint:8=facility, uint:16=card_number, 0b0",
|
||||||
facility=facility,
|
facility=facility,
|
||||||
card_number=card_number,
|
card_number=card_number,
|
||||||
)
|
)
|
||||||
bits[6] = bits[7:19].count(1) % 2 # even parity
|
bits[6] = cls.even_parity(bits)
|
||||||
bits[31] = bits[19:31].count(0) % 2 # odd parity
|
bits[31] = cls.odd_parity(bits)
|
||||||
return cls(bitstring.Bits(bits))
|
return cls(bitstring.Bits(bits))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -42,9 +50,9 @@ class Credential:
|
|||||||
|
|
||||||
if bits[:6].any(1):
|
if bits[:6].any(1):
|
||||||
raise Not26Bit(bits)
|
raise Not26Bit(bits)
|
||||||
if bits[6] != bits[7:19].count(1) % 2:
|
if bits[6] != cls.even_parity(bits):
|
||||||
raise InvalidParity(bits, "even")
|
raise InvalidParity(bits, "even")
|
||||||
if bits[31] != (bits[19:31].count(0) % 2):
|
if bits[31] != (cls.odd_parity(bits)):
|
||||||
raise InvalidParity(bits, "odd")
|
raise InvalidParity(bits, "odd")
|
||||||
|
|
||||||
return cls(bits)
|
return cls(bits)
|
||||||
|
@ -18,3 +18,13 @@ class CredentialTestCase(TestCase):
|
|||||||
cred = Credential.from_code(facility_code, card_number)
|
cred = Credential.from_code(facility_code, card_number)
|
||||||
hex_cred = Credential.from_hex(cred.hex)
|
hex_cred = Credential.from_hex(cred.hex)
|
||||||
self.assertEqual(cred, hex_cred)
|
self.assertEqual(cred, hex_cred)
|
||||||
|
|
||||||
|
def test_example_numbers(self):
|
||||||
|
examples = [
|
||||||
|
(100, 12345, "02C86073"),
|
||||||
|
]
|
||||||
|
|
||||||
|
for facility_code, card_number, hex_number in examples:
|
||||||
|
code_cred = Credential.from_code(facility_code, card_number)
|
||||||
|
hex_cred = Credential.from_hex(hex_number)
|
||||||
|
self.assertEqual(code_cred, hex_cred)
|
||||||
|
Loading…
Reference in New Issue
Block a user