Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 散列字符串值会导致Linux和Windows上C++;_C++_Boost_Hash_Hashcode - Fatal编程技术网

C++ 散列字符串值会导致Linux和Windows上C++;

C++ 散列字符串值会导致Linux和Windows上C++;,c++,boost,hash,hashcode,C++,Boost,Hash,Hashcode,我正在尝试散列单个std::string和std::vector值。我遵循和中的示例。当代码在Windows和Linux上编译和运行时,我得到了不同的结果 MyHasher.h的头文件如下所示 class MyHasher { private: MyHasher() = delete; public: static std::size_t hash(std::vector<std::string> ids); static std::size_t hash(std::

我正在尝试散列单个
std::string
std::vector
值。我遵循和中的示例。当代码在Windows和Linux上编译和运行时,我得到了不同的结果

MyHasher.h
的头文件如下所示

class MyHasher {
 private:
  MyHasher() = delete;
 public:
  static std::size_t hash(std::vector<std::string> ids);
  static std::size_t hash(std::string s);
  static void hashCombine(std::size_t &seed, std::size_t value);
};
std::size_t MyHasher::hash(std::vector<std::string> ids) {
  std::size_t seed = 0;
  for (auto id : ids) {
    std::size_t h = std::hash<std::string>{}(id);
    hashCombine(seed, h);
  }
  return seed;
}
std::size_t MyHasher::hash(std::string s) {
  std::size_t seed = 0;
  std::size_t h = std::hash<std::string>{}(s);
  hashCombine(seed, h);
  return seed;
}
void MyHasher::hashCombine(std::size_t &seed, std::size_t value) {
  seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
int main() {
  std::cout << std::to_string(MyHasher::hash("0")) << " | 0" << std::endl;
  std::cout << std::to_string(MyHasher::hash(std::vector<std::string>{"0"})) << " | 0" << std::endl;
  std::cout << std::to_string(MyHasher::hash(std::vector<std::string>{"0", "1"})) << " | 0 1" << std::endl;
  return 0;
}
2297668036269395695 | 0 2297668036269395695 | 0 10545066640295778616 | 0 1 12638135526163551848 | 0 12638135526163551848 | 0 1964774108746342951 | 0 1 然后,一个示例程序按如下方式运行

class MyHasher {
 private:
  MyHasher() = delete;
 public:
  static std::size_t hash(std::vector<std::string> ids);
  static std::size_t hash(std::string s);
  static void hashCombine(std::size_t &seed, std::size_t value);
};
std::size_t MyHasher::hash(std::vector<std::string> ids) {
  std::size_t seed = 0;
  for (auto id : ids) {
    std::size_t h = std::hash<std::string>{}(id);
    hashCombine(seed, h);
  }
  return seed;
}
std::size_t MyHasher::hash(std::string s) {
  std::size_t seed = 0;
  std::size_t h = std::hash<std::string>{}(s);
  hashCombine(seed, h);
  return seed;
}
void MyHasher::hashCombine(std::size_t &seed, std::size_t value) {
  seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
int main() {
  std::cout << std::to_string(MyHasher::hash("0")) << " | 0" << std::endl;
  std::cout << std::to_string(MyHasher::hash(std::vector<std::string>{"0"})) << " | 0" << std::endl;
  std::cout << std::to_string(MyHasher::hash(std::vector<std::string>{"0", "1"})) << " | 0 1" << std::endl;
  return 0;
}
2297668036269395695 | 0 2297668036269395695 | 0 10545066640295778616 | 0 1 12638135526163551848 | 0 12638135526163551848 | 0 1964774108746342951 | 0 1
intmain(){
在的文件中,明确提到:

实际的哈希函数取决于实现

散列函数只需要在程序的一次执行中为相同的输入生成相同的结果

我对一个哈希函数有点不确定,它总是为相同的输入返回相同的哈希值。我在谷歌上搜索了一下,但没有找到我敢展示的东西

假设MS VC++和g++的std库可能是不同的实现,不能期望它为相同的输入生成相同的哈希

仔细阅读cite的第二部分,您甚至不能期望相同的程序在不同的进程中(例如,启动、退出和再次启动时)为相同的输入生成相同的哈希


可能是一个解决方案:

  • 它是确定性的,这意味着相同的消息总是导致相同的散列
  • 可以快速计算任何给定消息的哈希值
  • 生成产生给定哈希值的消息是不可行的
  • 不可能找到具有相同哈希值的两条不同消息 对消息的一个小的更改应该广泛地更改哈希值,使新的哈希值看起来与旧的哈希值不相关()
与哈希函数相关。对于校验和,必须要求对相同的输入产生相同的输出(为了可靠)

因此,基于哈希函数的校验和实现也应该符合OP的要求

对这个问题的公认答案是建议


这让我想起了我最近听到的,但在我看来,它与OP可能具有的(我假设)类似的用例。

无关:
类MyHasher
看起来很像一个命名空间。OT:您应该通过常量引用将参数传递给
MyHasher::hash
。建议的附录(只是为了切中要害):问题的解决方案是提供您自己的底层哈希算法,这样您就可以保证在任何平台上都有相同的行为。@user4581301我已经尽力了。(我必须承认我不是专家。);-)你所涉及的领域比我要多。有很多选择供人们尝试。我刚刚注意到,你的加密哈希函数链接指向simple.wikipedia.org。如果你将其更改为en.wikipedia.org,那么属性列表将展开,第一行是:
它是确定性的,意味着相同的消息总是results在同一个散列中
。因此,我认为这回答了相同输入的相同散列的问题。@Frodyne谢谢你的宝贵提示。我回顾了我的答案。