rolling_crc.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // Copyright 2010 Google Inc. All rights reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Implements rolling CRC (e.g. for Rabin fingerprinting).
  15. #ifndef CRCUTIL_ROLLING_CRC_H_
  16. #define CRCUTIL_ROLLING_CRC_H_
  17. #include "base_types.h" // size_t, uint8
  18. #include "crc_casts.h" // TO_BYTE
  19. namespace crcutil {
  20. #pragma pack(push, 16)
  21. // CrcImplementation should provide:
  22. // - typename Crc
  23. // - typename TableEntry
  24. // - typename Word
  25. // - Crc CrcDefault(const void *data, size_t bytes, const Crc &start)
  26. // - const GfUtil<Crc> &Base() const
  27. template<typename CrcImplementation> class RollingCrc {
  28. public:
  29. typedef typename CrcImplementation::Crc Crc;
  30. typedef typename CrcImplementation::TableEntry TableEntry;
  31. typedef typename CrcImplementation::Word Word;
  32. RollingCrc() {}
  33. // Initializes internal data structures.
  34. // Retains reference to "crc" instance -- it is used by Start().
  35. RollingCrc(const CrcImplementation &crc,
  36. size_t roll_window_bytes,
  37. const Crc &start_value) {
  38. Init(crc, roll_window_bytes, start_value);
  39. }
  40. // Computes crc of "roll_window_bytes" using
  41. // "start_value" of "crc" (see Init()).
  42. Crc Start(const void *data) const {
  43. return crc_->CrcDefault(data, roll_window_bytes_, start_value_);
  44. }
  45. // Computes CRC of "roll_window_bytes" starting in next position.
  46. Crc Roll(const Crc &old_crc, size_t byte_out, size_t byte_in) const {
  47. return (old_crc >> 8) ^ in_[TO_BYTE(old_crc) ^ byte_in] ^ out_[byte_out];
  48. }
  49. // Initializes internal data structures.
  50. // Retains reference to "crc" instance -- it is used by Start().
  51. void Init(const CrcImplementation &crc,
  52. size_t roll_window_bytes,
  53. const Crc &start_value) {
  54. crc_ = &crc;
  55. roll_window_bytes_ = roll_window_bytes;
  56. start_value_ = start_value;
  57. Crc add = crc.Base().Canonize() ^ start_value;
  58. add = crc.Base().Multiply(add, crc.Base().Xpow8N(roll_window_bytes));
  59. add ^= crc.Base().Canonize();
  60. Crc mul = crc.Base().One() ^ crc.Base().Xpow8N(1);
  61. add = crc.Base().Multiply(add, mul);
  62. mul = crc.Base().XpowN(8 * roll_window_bytes + crc.Base().Degree());
  63. for (size_t i = 0; i < 256; ++i) {
  64. out_[i] = static_cast<TableEntry>(
  65. crc.Base().MultiplyUnnormalized(
  66. static_cast<Crc>(i), 8, mul) ^ add);
  67. }
  68. for (size_t i = 0; i < 256; ++i) {
  69. in_[i] = crc.crc_word_[sizeof(Word) - 1][i];
  70. }
  71. }
  72. // Returns start value.
  73. Crc StartValue() const { return start_value_; }
  74. // Returns length of roll window.
  75. size_t WindowBytes() const { return roll_window_bytes_; }
  76. protected:
  77. TableEntry in_[256];
  78. TableEntry out_[256];
  79. // Used only by Start().
  80. Crc start_value_;
  81. const CrcImplementation *crc_;
  82. size_t roll_window_bytes_;
  83. } GCC_ALIGN_ATTRIBUTE(16);
  84. #pragma pack(pop)
  85. } // namespace crcutil
  86. #endif // CRCUTIL_ROLLING_CRC_H_