Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.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++ “双向”;“散列”;弦的_C++_Hash - Fatal编程技术网

C++ “双向”;“散列”;弦的

C++ “双向”;“散列”;弦的,c++,hash,C++,Hash,我想从一个字符串生成int,并能够将其生成回来。 类似于散列函数,但是双向函数。 我希望在我的应用程序中使用ints作为ID,但希望能够在日志记录或调试时将其转换回来 比如: 我听说CRC32稍作修改,速度快,100%可逆,但我找不到,我自己也写不出来 有什么提示我应该用什么? 谢谢大家! 编辑 我刚刚找到了CRC32的来源: 贾森·格雷戈里:游戏引擎架构 报价: “与任何哈希系统一样,冲突也是可能的(即,两个不同的字符串可能以相同的哈希代码结束)。但是,使用合适的哈希函数,我们几乎可以保证在游

我想从一个字符串生成int,并能够将其生成回来。 类似于散列函数,但是双向函数。 我希望在我的应用程序中使用ints作为ID,但希望能够在日志记录或调试时将其转换回来

比如:

我听说CRC32稍作修改,速度快,100%可逆,但我找不到,我自己也写不出来

有什么提示我应该用什么? 谢谢大家!

编辑 我刚刚找到了CRC32的来源:

贾森·格雷戈里:游戏引擎架构

报价:


“与任何哈希系统一样,冲突也是可能的(即,两个不同的字符串可能以相同的哈希代码结束)。但是,使用合适的哈希函数,我们几乎可以保证在游戏中可能使用的所有合理输入字符串不会发生冲突。毕竟,32位哈希选择表示超过40亿个可能的值。因此,如果我们的哈希函数能够很好地将字符串分布在这个非常大的范围内,我们可以我们不太可能发生冲突。在《淘气狗》中,我们使用了CRC-32算法的一种变体来散列字符串,在《未知:德雷克的财富》的两年多的开发过程中,我们没有遇到过一次冲突。”

你可以看到完美的散列

只有在预先知道所有可能的字符串时,它才起作用。在实践中,您可以通过此操作创建一个有限范围的“哈希”映射,您可以反转查找

通常,[哈希代码+哈希算法]永远不足以恢复原始值。但是,使用一个完美的散列,冲突被定义为不可能发生的,因此如果源域(值列表)已知,则可以获取源值


gperf
是一个众所周知的、由来已久的程序,用于在c/c++代码中生成完美的散列。还有很多(参见维基百科页面)

将任意长度的字符串缩减为固定大小的int在数学上是不可能逆转的。看见字符串的数量几乎是无限的,但只有2^32位整数

32位散列(假设int为32位)很容易发生冲突。所以它也不是一个好的唯一ID

有一些哈希函数允许您使用预定义的哈希创建消息,但它很可能不是原始消息。这被称为一个

对于您的问题,最好的办法似乎是创建一个字典,将整数ID映射到字符串并返回



要在散列n个字符串时获得冲突的可能性,请签出。该上下文中最重要的属性是,一旦哈希消息的数量接近可用哈希值数量的平方根,冲突就有可能发生。因此,对于32位整数,如果散列65000个字符串,可能会发生冲突。但是如果你运气不好,它可能会发生得更早。

这是不可能的。散列是不可返回的函数-根据定义。

您需要的是加密。根据定义,散列是一种方法。您可以尝试使用简单的XOR加密和一些值的加法/减法


。。。通过谷歌搜索还有更多…

我完全有你需要的。它被称为“指针”。在这个系统中,“指针”总是唯一的,并且总是可以用来恢复字符串。它可以“指向”任何长度的任何字符串。作为奖励,它还具有与int相同的大小。您可以使用
&
操作数获得指向字符串的“指针”,如我的示例代码所示:

#include <string>
int main() {
    std::string s = "Hai!";
    std::string* ptr = &s; // this is a pointer
    std::string copy = *ptr; // this retrieves the original string
    std::cout << copy; // prints "Hai!"
}
#包括
int main(){
std::string s=“Hai!”;
std::string*ptr=&s;//这是一个指针
std::string copy=*ptr;//这将检索原始字符串

正如大家所提到的,不可能有一个“可逆散列”。但是,也有其他选择(比如加密)

另一种方法是使用任何无损算法压缩/解压字符串


这是一种简单、完全可逆的方法,没有可能的冲突。

这不是散列的意思。你在说这个吗?只有CRC32的一个特例是可逆的:没有CRC32做你认为它做的事情,它的主要目的是检测位错误。@SLaks我知道散列的意思,但我找不到其他词。这就是为什么我使用引号,写了<代码>类似之类的东西,使用“代码>双向<代码> >这不会给出int,它不绑定到C++,但是对于搜索的缘故,人们可能会对Base64编码感兴趣。(例如,在bash中,
echo which | base64
给出了
d2hhdGV2ZXIK
,它
base64-d
解码回
which
)。+1用于公式:不过,公平地说,指针值在两次运行之间是不一样的。这有很多问题:1)ID只能在单个进程中使用2)您需要让字符串保持足够长的活动时间3)如果您将此应用于多个内容相同但引用不相同的字符串,则会得到不同的ID。@CodeInChaos谢谢,我只是就要写了myself@CodeInChaos:您可以使用
boost
来获取进程间指针。您也可以使用其他类型的智能指针来序列化指针。其次,他本来只打算使用几个常量字符串,所以生存期和引用问题没什么大不了的。“作为奖励,它还具有与int相同的大小。"I32LP64不同意在实践中,我几乎总是使用字典来解决这个问题。但偶尔它可能会带来性能方面的好处。同意。不过,一个好处是,可以只共享哈希函数。现在,任何客户端都可以在不必知道可能输入值的完整表的情况下获得正确的哈希和。这对具有较大源代码域的分布式软件谢谢您的回答。由于各种原因,我不想使用字典。我对
#include <string>
int main() {
    std::string s = "Hai!";
    std::string* ptr = &s; // this is a pointer
    std::string copy = *ptr; // this retrieves the original string
    std::cout << copy; // prints "Hai!"
}