kraskevich

anti hash test generator

Feb 17th, 2013
240
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.09 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <string.h>
  4. #include <sstream>
  5. #include <cassert>
  6. #include <cstdlib>
  7. #include <complex>
  8. #include <cctype>
  9. #include <cstdio>
  10. #include <vector>
  11. #include <cmath>
  12. #include <ctime>
  13. #include <deque>
  14. #include <queue>
  15. #include <stack>
  16. #include <map>
  17. #include <set>
  18.  
  19. using namespace std;
  20.  
  21.  
  22. /*
  23.  This is an anti hash test generator
  24.  It can find collisions for different polynomial hashes
  25. */
  26.  
  27.  
  28. const int N = 22; //the length of strings generated to make collision
  29.  
  30.  
  31.  
  32. int rnd[1 << 22];
  33.  
  34. class MyRandom //specific random numbers generator
  35. {
  36.     int count;
  37. public:
  38.     MyRandom()
  39.     {
  40.         for (int i = 0; i < (1 << N); ++i)
  41.             rnd[i] = i;
  42.         random_shuffle(rnd, rnd + (1 << N));
  43.         count = 0;
  44.     }
  45.  
  46.     void reset()
  47.     {
  48.         count = 0;
  49.     }
  50.  
  51.     int random()
  52.     {
  53.         count %= (1 << N);
  54.         return rnd[count++];
  55.     }
  56. };
  57.  
  58. MyRandom random;
  59.  
  60.  
  61.  
  62. string makeString(int mask) //converts bitmask into an 'a'-'b' string
  63. {
  64.     string result;
  65.     for (int i = 0; i < N; ++i)
  66.     {
  67.         if (mask & (1 << i))
  68.             result += 'b';
  69.         else
  70.             result += 'a';
  71.     }
  72.     return result;
  73. }
  74.  
  75.  
  76. long long getHash(int mask, long long base, long long mod, long long valueA, long long valueB) //this function calculates hash value
  77. {
  78.     long long currentPow = 1;
  79.     long long HASH = 0;
  80.     for (int i = 0; i < N; ++i)
  81.     {
  82.         if (mask & (1 << i))
  83.             HASH += currentPow * valueB;
  84.         else
  85.             HASH += currentPow * valueA;
  86.         HASH %= mod;
  87.         currentPow *= base;
  88.         currentPow %= mod;
  89.     }
  90.     return HASH;
  91. }
  92.  
  93. long long getHash(string s, long long base, long long mod, long long valueA, long long valueB)
  94. {
  95.     long long currentPow = 1;
  96.     long long HASH = 0;
  97.     for (int i = 0; i < s.length(); ++i)
  98.     {
  99.         if (s[i] == 'b')
  100.             HASH += currentPow * valueB;
  101.         else
  102.             HASH += currentPow * valueA;
  103.         HASH %= mod;
  104.         currentPow *= base;
  105.         currentPow %= mod;
  106.     }
  107.     return HASH;
  108. }
  109.  
  110. /*
  111.  Hash table
  112. */
  113.  
  114. const int CELLS = 1000 * 1000 + 13;
  115. int top[CELLS];
  116. const int MAX_SZ = (1 << N);
  117. long long key[MAX_SZ];
  118. int go[MAX_SZ];
  119. int value[MAX_SZ];
  120.  
  121. long long ABS(long long a)
  122. {
  123.     return (a > 0 ? a : -a);
  124. }
  125.  
  126. class HashTable
  127. {
  128.     int sz;
  129. public:
  130.     HashTable()
  131.     {
  132.         sz = 0;
  133.         for (int i = 0; i < CELLS; ++i)
  134.             top[i] = -1;
  135.     }
  136.  
  137.     void clear()
  138.     {
  139.         sz = 0;
  140.         for (int i = 0; i < CELLS; ++i)
  141.             top[i] = -1;
  142.     }
  143.  
  144.     void addKey(long long _key, int _value)
  145.     {
  146.         int cell = ABS(_key) % CELLS;
  147.         int id = sz++;
  148.         key[id] = _key;
  149.         value[id] = _value;
  150.         go[id] = top[cell];
  151.         top[cell] = id;
  152.     }
  153.  
  154.     int getValue(long long _key) //returns -1 if there's no such key
  155.     {
  156.         int cell = ABS(_key) % CELLS;
  157.         int ptr = top[cell];
  158.         while (ptr >= 0)
  159.         {
  160.             if (key[ptr] == _key)
  161.                 return value[ptr];
  162.             ptr = go[ptr];
  163.         }
  164.         return -1;
  165.     }
  166. };
  167.  
  168. HashTable was;
  169.  
  170.  
  171.  
  172.  
  173. pair<string, string> buildMod(long long base, long long mod, long long valueA, long long valueB)
  174. {
  175.     random.reset();
  176.     was.clear();
  177.  
  178.     for (;;)
  179.     {
  180.         int mask = random.random();
  181.         long long HASH = getHash(mask, base, mod, valueA, valueB);
  182.         int prevMask = was.getValue(HASH);
  183.         if (prevMask == -1)
  184.         {
  185.             was.addKey(HASH, mask);
  186.         }
  187.         else
  188.         {
  189.             string a = makeString(mask);
  190.             string b = makeString(prevMask);
  191.             return pair<string, string> (a, b);
  192.         }
  193.     }
  194. }
  195.  
  196.  
  197.  
  198. const int LEN = (1 << 12);
  199.  
  200. pair<string, string> buildPow2()
  201. {
  202.     string current;
  203.     for (int i = 0; i < LEN; ++i)
  204.     {
  205.         if (__builtin_popcount(i) % 2 == 0)
  206.             current += 'a';
  207.         else
  208.             current += 'b';
  209.     }
  210.     string a = current.substr(0, LEN / 2);
  211.     string b = current.substr(LEN / 2, LEN / 2);
  212.     return pair<string, string> (a, b);
  213. }
  214.  
  215.  
  216. /*
  217.  This structure describes one hash.
  218.  It contians it's base and modulo.
  219.  If the module is power of 2,
  220.  then there should be zero instead.
  221.  rev should be 0 if hash value is calculated from left to right
  222.  and 1 otherwise
  223. */
  224.  
  225. struct HashPair
  226. {
  227.     long long base;
  228.     long long mod;
  229.     int rev;
  230.  
  231.     void read()
  232.     {
  233.         cin >> base >> mod;
  234.         cin >> rev;
  235.     }
  236. };
  237.  
  238. bool cmp(HashPair a, HashPair b)
  239. {
  240.     return a.mod > b.mod;
  241. }
  242.  
  243. pair<string, string> buildTest(vector<HashPair> h)
  244. {
  245.     if (h.size() == 0)
  246.     {
  247.         string a = "a";
  248.         string b = "b";
  249.         return pair<string, string> (a, b);
  250.     }
  251.  
  252.     HashPair last = h.back();
  253.     h.pop_back();
  254.     pair<string, string> prev = buildTest(h);
  255.  
  256.     if (last.mod == 0)
  257.     {
  258.         pair<string, string> result;
  259.         pair<string, string> temp = buildPow2();
  260.         for (int i = 0; i < temp.first.length(); ++i)
  261.         {
  262.             if (temp.first[i] == 'a')
  263.                 result.first += prev.first;
  264.             else
  265.                 result.first += prev.second;
  266.             if (temp.second[i] == 'a')
  267.                 result.second += prev.first;
  268.             else
  269.                 result.second += prev.second;
  270.         }
  271.  
  272.         return result;
  273.     }
  274.  
  275.     long long valueA = getHash(prev.first, last.base, last.mod, 1, 2);
  276.     long long valueB = getHash(prev.second, last.base, last.mod, 1, 2);
  277.     long long initBase = last.base;
  278.     for (int i = 1; i < prev.first.length(); ++i)
  279.         last.base *= initBase, last.base %= last.mod;
  280.  
  281.     pair<string, string> temp = buildMod(last.base, last.mod, valueA, valueB);
  282.     if (last.rev)
  283.     {
  284.         reverse(temp.first.begin(), temp.first.end());
  285.         reverse(temp.second.begin(), temp.second.end());
  286.     }
  287.  
  288.     pair<string, string> result;
  289.     for (int i = 0; i < temp.first.length(); ++i)
  290.     {
  291.         if (temp.first[i] == 'a')
  292.             result.first += prev.first;
  293.         else
  294.             result.first += prev.second;
  295.         if (temp.second[i] == 'a')
  296.             result.second += prev.first;
  297.         else
  298.             result.second += prev.second;
  299.     }
  300.  
  301.     return result;
  302. }
  303.  
  304.  
  305. void solve()
  306. {
  307.     int n;
  308.     cin >> n;
  309.  
  310.     vector<HashPair> h(n); //vector contains all hashes
  311.     for (int i = 0; i < n; ++i)
  312.         h[i].read();
  313.  
  314.     sort(h.begin(), h.end(), cmp);
  315.     while (h.size() >= 2 && h[(int)h.size() - 1].mod == 0 && h[(int)h.size() - 2].mod == 0)
  316.         h.pop_back();
  317.  
  318.     pair<string, string> result = buildTest(h);
  319.     assert(result.first != result.second);
  320.  
  321.     /*
  322.      Be careful!
  323.      If there're many hashes then the result might be very long!
  324.     */
  325.  
  326.     cerr << "The length is: " << result.first.length() << endl;
  327.     cout << result.first << endl;
  328.     cout << result.second << endl;
  329. }
  330.  
  331.  
  332. int main()
  333. {
  334.     freopen("input.txt", "r", stdin);
  335.     freopen("output.txt", "w", stdout);
  336.  
  337.     solve();
  338.  
  339.     fclose(stdin);
  340.     fclose(stdout);
  341.  
  342.     return 0;
  343. }
Advertisement
Add Comment
Please, Sign In to add comment