CRC8.h 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*
  2. * Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Types.h>
  8. #include <LibCrypto/Checksum/ChecksumFunction.h>
  9. namespace Crypto::Checksum {
  10. // A generic 8-bit Cyclic Redundancy Check.
  11. // Note that as opposed to CRC32, this class operates with MSB first, so the polynomial must not be reversed.
  12. // For example, the polynomial x⁸ + x² + x + 1 is represented as 0x07 and not 0xE0.
  13. template<u8 polynomial>
  14. class CRC8 : public ChecksumFunction<u8> {
  15. public:
  16. // This is a big endian table, while CRC-32 uses a little endian table.
  17. static constexpr auto generate_table()
  18. {
  19. Array<u8, 256> data {};
  20. u8 value = 0x80;
  21. auto i = 1u;
  22. do {
  23. if ((value & 0x80) != 0) {
  24. value = polynomial ^ (value << 1);
  25. } else {
  26. value = value << 1;
  27. }
  28. for (auto j = 0u; j < i; ++j) {
  29. data[i + j] = value ^ data[j];
  30. }
  31. i <<= 1;
  32. } while (i < 256);
  33. return data;
  34. }
  35. static constexpr auto table = generate_table();
  36. virtual ~CRC8() = default;
  37. CRC8() = default;
  38. CRC8(ReadonlyBytes data)
  39. {
  40. update(data);
  41. }
  42. CRC8(u8 initial_state, ReadonlyBytes data)
  43. : m_state(initial_state)
  44. {
  45. update(data);
  46. }
  47. // FIXME: This implementation is naive and slow.
  48. // Figure out how to adopt the slicing-by-8 algorithm (see CRC32) for 8 bit polynomials.
  49. virtual void update(ReadonlyBytes data) override
  50. {
  51. for (size_t i = 0; i < data.size(); i++) {
  52. size_t table_index = (m_state ^ data.at(i)) & 0xFF;
  53. m_state = (table[table_index] ^ (static_cast<u32>(m_state) << 8)) & 0xFF;
  54. }
  55. }
  56. virtual u8 digest() override
  57. {
  58. return m_state;
  59. }
  60. private:
  61. u8 m_state { 0 };
  62. };
  63. }