You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // roller.hpp
  2. // Copyright (C) 2022 MicroNeil Research Corporation.
  3. //
  4. // This software is released under the MIT license. See LICENSE.TXT.
  5. //
  6. // Roller is a naive rolling hash system for rapid string searches.
  7. // Roller32 accommodates matches up to 4 bytes.
  8. // Roller64 accommodates matches up to 8 bytes.
  9. #pragma once
  10. #include <cstdint>
  11. #include <string>
  12. #include <vector>
  13. namespace codedweller {
  14. class Roller32 {
  15. private:
  16. uint_fast32_t roller;
  17. public:
  18. Roller32() : roller(0) {}
  19. uint_fast32_t value() const { return roller; }
  20. uint_fast32_t add(uint8_t byte) {
  21. roller = roller << 8 | byte;
  22. return roller;
  23. }
  24. };
  25. class Roller64 {
  26. private:
  27. uint_fast64_t roller;
  28. public:
  29. Roller64() : roller(0) {}
  30. uint_fast64_t value() const { return roller; }
  31. uint_fast64_t add(uint8_t byte) {
  32. roller = roller << 8 | byte;
  33. return roller;
  34. }
  35. };
  36. class RollerMatch32 {
  37. private:
  38. uint_fast32_t match;
  39. uint_fast32_t mask;
  40. public:
  41. RollerMatch32(const std::vector<unsigned char> pattern) {
  42. match = mask = 0;
  43. size_t ingest = std::min(sizeof(uint_fast32_t), pattern.size());
  44. Roller32 matcher;
  45. Roller32 masker;
  46. for(size_t count = 0; count < ingest; count++) {
  47. matcher.add(pattern.at(count));
  48. masker.add(0xFF);
  49. }
  50. match = matcher.value();
  51. mask = masker.value();
  52. }
  53. RollerMatch32(const std::string pattern) {
  54. match = mask = 0;
  55. size_t ingest = std::min(sizeof(uint_fast32_t), pattern.size());
  56. Roller32 matcher;
  57. Roller32 masker;
  58. for(size_t count = 0; count < ingest; count++) {
  59. matcher.add(pattern.at(count));
  60. masker.add(0xFF);
  61. }
  62. match = matcher.value();
  63. mask = masker.value();
  64. }
  65. bool matches(const Roller32 roller) {
  66. return (match == (roller.value() & mask));
  67. }
  68. };
  69. class RollerMatch64 {
  70. private:
  71. uint_fast64_t match;
  72. uint_fast64_t mask;
  73. public:
  74. RollerMatch64(const std::vector<unsigned char> pattern) {
  75. match = mask = 0;
  76. size_t ingest = std::min(sizeof(uint_fast64_t), pattern.size());
  77. Roller64 matcher;
  78. Roller64 masker;
  79. for(size_t count = 0; count < ingest; count++) {
  80. matcher.add(pattern.at(count));
  81. masker.add(0xFF);
  82. }
  83. match = matcher.value();
  84. mask = masker.value();
  85. }
  86. RollerMatch64(const std::string pattern) {
  87. match = mask = 0;
  88. size_t ingest = std::min(sizeof(uint_fast64_t), pattern.size());
  89. Roller64 matcher;
  90. Roller64 masker;
  91. for(size_t count = 0; count < ingest; count++) {
  92. matcher.add(pattern.at(count));
  93. masker.add(0xFF);
  94. }
  95. match = matcher.value();
  96. mask = masker.value();
  97. }
  98. bool matches(const Roller64 roller) {
  99. return (match == (roller.value() & mask));
  100. }
  101. };
  102. }