util.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. import re
  22. __all__ = [
  23. "bitreverse",
  24. "poly2int",
  25. "int2poly",
  26. ]
  27. def bitreverse(value, nrBits):
  28. """Reverse the bits in an integer.
  29. """
  30. ret = 0
  31. for _ in range(nrBits):
  32. ret = (ret << 1) | (value & 1)
  33. value >>= 1
  34. return ret
  35. def poly2int(polyString, nrBits, shiftRight=False):
  36. """Convert polynomial coefficient string to binary integer.
  37. """
  38. polyString = polyString.lower().strip();
  39. if polyString.startswith("0x"):
  40. # Hex format
  41. try:
  42. poly = int(polyString[2:], 16)
  43. except ValueError:
  44. raise ValueError("Invalid polynomial coefficient format.")
  45. else:
  46. try:
  47. # Decimal format
  48. poly = int(polyString, 10)
  49. except ValueError:
  50. # Polynomial coefficient format
  51. polyString, _ = re.subn(r"\s+", "", polyString)
  52. poly = 0
  53. try:
  54. for bit in polyString.split("+"):
  55. if bit.startswith("x^"):
  56. poly |= 1 << int(bit[2:], 10)
  57. elif bit == "x":
  58. poly |= 1 << 1
  59. elif bit == "1":
  60. poly |= 1 << 0
  61. else:
  62. raise ValueError
  63. except ValueError:
  64. raise ValueError("Invalid polynomial coefficient format.")
  65. poly &= (1 << nrBits) - 1
  66. if shiftRight:
  67. poly = bitreverse(poly, nrBits)
  68. return poly
  69. def int2poly(poly, nrBits, shiftRight=False):
  70. """Convert binary integer polynomial coefficient to string.
  71. """
  72. poly &= (1 << nrBits) - 1
  73. if shiftRight:
  74. poly = bitreverse(poly, nrBits)
  75. p = []
  76. shift = 0
  77. while poly:
  78. if poly & 1:
  79. if shift == 0:
  80. p.append("1")
  81. elif shift == 1:
  82. p.append("x")
  83. else:
  84. p.append(f"x^{shift}")
  85. shift += 1
  86. poly >>= 1
  87. p.append(f"x^{nrBits}")
  88. return " + ".join(reversed(p))