reference.py 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. # vim: ts=8 sw=8 noexpandtab
  2. #
  3. # CRC code generator
  4. #
  5. # Copyright (c) 2019-2023 Michael Büsch <m@bues.ch>
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License along
  18. # with this program; if not, write to the Free Software Foundation, Inc.,
  19. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  20. #
  21. __all__ = [
  22. "CrcReference",
  23. ]
  24. from typing import Iterable
  25. class CrcReference:
  26. """Generic CRC reference implementation.
  27. """
  28. @classmethod
  29. def crc(cls,
  30. crc: int,
  31. data: int,
  32. polynomial: int,
  33. nrCrcBits: int,
  34. nrDataBits: int = 8,
  35. shiftRight: bool = False):
  36. crcMask = (1 << nrCrcBits) - 1
  37. msb = 1 << (nrCrcBits - 1)
  38. lsb = 1
  39. if shiftRight:
  40. for i in range(nrDataBits):
  41. crc ^= data & 1
  42. data >>= 1
  43. if crc & lsb:
  44. crc = ((crc >> 1) ^ polynomial) & crcMask
  45. else:
  46. crc = (crc >> 1) & crcMask
  47. else:
  48. for i in range(nrDataBits):
  49. crc ^= ((data >> (nrDataBits - 1)) & 1) << (nrCrcBits - 1)
  50. data <<= 1
  51. if crc & msb:
  52. crc = ((crc << 1) ^ polynomial) & crcMask
  53. else:
  54. crc = (crc << 1) & crcMask
  55. return crc
  56. @classmethod
  57. def crcBlock(cls,
  58. crc: int,
  59. data: Iterable,
  60. polynomial: int,
  61. nrCrcBits: int,
  62. nrDataBits: int = 8,
  63. shiftRight: bool = False,
  64. preFlip: bool = False,
  65. postFlip: bool = False):
  66. crcMask = (1 << nrCrcBits) - 1
  67. if preFlip:
  68. crc ^= crcMask
  69. for b in data:
  70. crc = cls.crc(crc=crc,
  71. data=b,
  72. polynomial=polynomial,
  73. nrCrcBits=nrCrcBits,
  74. nrDataBits=nrDataBits,
  75. shiftRight=shiftRight)
  76. if postFlip:
  77. crc ^= crcMask
  78. return crc