我在分配时遇到了一些麻烦,我要为给定函数创建一个算法,该算法接受一个字符串并将其转换为40位散列。有了这个,我必须找到两个具有相同值的不同哈希。在给出合理的概率之前,TA给了我们一个关于使用生日悖论来找到不同字符串数量的暗示。我的问题是,我应该如何处理这个问题,因为没有字符串,也没有设定长度。
答案 0 :(得分:3)
考虑到关于“生日悖论”的暗示(这根本不是悖论),我假设你的作业要求你生成许多字符串并对它们进行散列并发现两个发生碰撞。
由于您使用的是40位散列函数,因此您需要尝试使用2 20 字符串(平均)来查找第一次碰撞。接近它的一种方法是生成和散列任何可以使用的字符串,长度为零及以上。
这样做的一种方法是:(我实际上没有尝试过任何此代码。)
using std::string;
template <typename F>
bool GenAllStrings_Worker (string & s, unsigned idx, string const & char_set,
unsigned long long & cnt, F f)
{
if (idx >= s.size())
return f(s, ++cnt);
for (auto c : char_set)
{
s[idx] = c;
if (GenAllStrings_Worker(s, idx + 1, char_set, cnt, f))
return true;
}
return false;
}
// Continues generating successively longer strings until "f" returns true.
// Passes each generated string and number of strings generated so far to "f".
template <typename F>
void GenAllStrings (string const & char_set, F f)
{
unsigned long long cnt = 0;
for (unsigned len = 0; ; ++len)
{
string s (len, '?');
if (GenAllStrings_Worker (s, 0, char_set, cnt, f))
return;
}
}
您可以像这样使用它:(不要忘记您需要提供hash_code
类型和MyHashFunction
功能。)
std::unordered_map<hash_code, string> generated_hashes;
GenAllStrings ("abcdef...ABCD...0123...whatever",
[&](string const & s, unsigned long long cnt){
hash_code h = MyHashFunction(s);
if (generated_hashes.find(h) != generated_hashes.end())
{
std::cout << "#" << cnt << " - Found a collision: '" << s <<"'"
<< " collides with '" << generated_hashes[h] << "'"
<< ", with a hash of " << h << std::endl;
return true;
}
h[h] = s;
return false;
});
我写了我传入GenAllStrings
函数的lambda,在第一次碰撞后停止;但是你可以产生你想要的许多碰撞(或有时间),在达到一定长度的字符串后停止等等。
答案 1 :(得分:1)
提示:如果你应用了生日悖论,你需要多少个随机字符串才能使这些字符串中的2个具有相同的40位散列的概率很大?
为什么不编写一个生成那么多字符串的程序,并试图找到碰撞?