crc32.hpp 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #pragma once
  2. #include <nall/hash/hash.hpp>
  3. namespace nall::Hash {
  4. struct CRC32 : Hash {
  5. using Hash::input;
  6. CRC32(array_view<uint8_t> buffer = {}) {
  7. reset();
  8. input(buffer);
  9. }
  10. auto reset() -> void override {
  11. checksum = ~0;
  12. }
  13. auto input(uint8_t value) -> void override {
  14. checksum = (checksum >> 8) ^ table(checksum ^ value);
  15. }
  16. auto output() const -> vector<uint8_t> {
  17. vector<uint8_t> result;
  18. for(auto n : reverse(range(4))) result.append(~checksum >> n * 8);
  19. return result;
  20. }
  21. auto value() const -> uint32_t {
  22. return ~checksum;
  23. }
  24. private:
  25. static auto table(uint8_t index) -> uint32_t {
  26. static uint32_t table[256] = {0};
  27. static bool initialized = false;
  28. if(!initialized) {
  29. initialized = true;
  30. for(auto index : range(256)) {
  31. uint32_t crc = index;
  32. for(auto bit : range(8)) {
  33. crc = (crc >> 1) ^ (crc & 1 ? 0xedb8'8320 : 0);
  34. }
  35. table[index] = crc;
  36. }
  37. }
  38. return table[index];
  39. }
  40. uint32_t checksum = 0;
  41. };
  42. }