memberPlumbing/hid/Credential.py

39 lines
1.3 KiB
Python

import bitstring
# Reference for H10301 card format:
# https://www.hidglobal.com/sites/default/files/hid-understanding_card_data_formats-wp-en.pdf
class Credential:
def __init__(self, code=None, hex=None):
if code is None and hex is None:
raise TypeError("Must set either code or hex for a Credential")
elif code is not None and hex is not None:
raise TypeError("Cannot set both code and hex for a Credential")
elif code is not None:
self.bits = bitstring.pack(
'0b000000, 0b0, uint:8=facility, uint:16=number, 0b0',
facility=code[0], number=code[1])
self.bits[6] = self.bits[7:19].count(1) % 2 # even parity
self.bits[31] = not (self.bits[19:31].count(1) % 2) # odd parity
elif hex is not None:
self.bits = bitstring.Bits(hex=hex)
def __repr__(self):
return f"Credential({self.code})"
def __eq__(self, other):
return self.bits == other.bits
def __hash__(self):
return self.bits.int
@property
def code(self):
facility = self.bits[7:15].uint
code = self.bits[15:31].uint
return (facility, code)
@property
def hex(self):
return self.bits.hex.upper()