1
0
mirror of https://github.com/mjg59/python-broadlink.git synced 2024-11-21 22:51:41 +01:00

Encapsulate crc16() to avoid global (#566)

This commit is contained in:
Felipe Martins Diel 2021-04-01 15:02:35 -03:00 committed by Felipe Martins Diel
parent 86b5d0727c
commit 4e1e690762
2 changed files with 35 additions and 29 deletions

View File

@ -3,7 +3,7 @@ from typing import List
from . import exceptions as e
from .device import device
from .helpers import crc16
from .helpers import CRC16
class hysen(device):
@ -19,7 +19,7 @@ class hysen(device):
def send_request(self, input_payload: bytes) -> bytes:
"""Send a request to the device."""
crc = crc16(input_payload)
crc = CRC16.calculate(input_payload)
# first byte is length, +2 for CRC16
request_payload = bytearray([len(input_payload) + 2, 0x00])
@ -40,7 +40,7 @@ class hysen(device):
raise ValueError(
"hysen_response_error", "first byte of response is not length"
)
crc = crc16(response_payload[2:response_payload_len])
crc = CRC16.calculate(response_payload[2:response_payload_len])
if (response_payload[response_payload_len] == crc & 0xFF) and (
response_payload[response_payload_len + 1] == (crc >> 8) & 0xFF
):

View File

@ -1,32 +1,38 @@
"""Helper functions."""
"""Helper functions and classes."""
import typing as t
_crc16_cache = {}
class CRC16: # pylint: disable=R0903
"""Helps with CRC-16 calculation.
def crc16(
sequence: t.Sequence[int],
polynomial: int = 0xA001, # Default: Modbus CRC-16.
init_value: int = 0xFFFF,
) -> int:
"""Calculate the CRC-16 of a sequence of integers."""
global _crc16_cache
CRC tables are cached for performance.
"""
try:
crc_table = _crc16_cache[polynomial]
except KeyError:
crc_table = []
for dividend in range(0, 256):
remainder = dividend
for _ in range(0, 8):
if remainder & 1:
remainder = remainder >> 1 ^ polynomial
else:
remainder = remainder >> 1
crc_table.append(remainder)
_crc16_cache[polynomial] = crc_table
_cache = {}
crc = init_value
for item in sequence:
crc = crc >> 8 ^ crc_table[(crc ^ item) & 0xFF]
return crc
@classmethod
def calculate(
cls,
sequence: t.Sequence[int],
polynomial: int = 0xA001, # Modbus CRC-16.
init_value: int = 0xFFFF,
) -> int:
"""Calculate the CRC-16 of a sequence of integers."""
try:
crc_table = cls._cache[polynomial]
except KeyError:
crc_table = []
for dividend in range(0, 256):
remainder = dividend
for _ in range(0, 8):
if remainder & 1:
remainder = remainder >> 1 ^ polynomial
else:
remainder = remainder >> 1
crc_table.append(remainder)
cls._cache[polynomial] = crc_table
crc = init_value
for item in sequence:
crc = crc >> 8 ^ crc_table[(crc ^ item) & 0xFF]
return crc