Skip to content

Commit

Permalink
Improve crc calculation.
Browse files Browse the repository at this point in the history
Use functools.reduce to facilitate checksum calculation.
  • Loading branch information
denpamusic committed Oct 20, 2023
1 parent 8763bc0 commit 8234dfd
Showing 1 changed file with 16 additions and 11 deletions.
27 changes: 16 additions & 11 deletions pyplumio/helpers/uid.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
"""Contains an UID helpers."""
from __future__ import annotations

from functools import reduce
from typing import Final


def unpack_uid(message: bytearray, offset: int = 0) -> str:
"""Decode and return a complete UID string."""
length = message[offset]
offset += 1
uid = message[offset : length + offset]

return _encode_base5(uid + _uid_crc(uid))
return _base5(uid + _crc16(uid))


def _encode_base5(data: bytes) -> str:
def _base5(data: bytes) -> str:
"""Encode bytes to a base5 encoded string."""
key_string = "0123456789ABCDEFGHIJKLMNZPQRSTUV"
number = int.from_bytes(data, "little")
Expand All @@ -23,18 +26,20 @@ def _encode_base5(data: bytes) -> str:
return output


def _uid_crc(message: bytes) -> bytes:
"""Return an UID CRC."""
crc_value = 0xA3A3
for byte in message:
crc_value = _uid_byte(crc_value ^ byte)
CRC: Final = 0xA3A3
POLYNOMIAL: Final = 0xA001

return crc_value.to_bytes(byteorder="little", length=2)

def _crc16(message: bytes) -> bytes:
"""Return an UID CRC."""
crc16 = reduce(_crc16_byte, message, CRC)
return crc16.to_bytes(byteorder="little", length=2)


def _uid_byte(byte: int) -> int:
def _crc16_byte(crc: int, byte: int) -> int:
"""Return a byte CRC."""
crc ^= byte
for _ in range(8):
byte = (byte >> 1) ^ 0xA001 if byte & 1 else byte >> 1
crc = (crc >> 1) ^ POLYNOMIAL if crc & 1 else crc >> 1

return byte
return crc

0 comments on commit 8234dfd

Please sign in to comment.