编译时间(预处理器)字符串散列

Ash*_*Ash 15 hash c-preprocessor

有没有办法在编译时使用C/C++预处理器(甚至模板元编程)创建字符串的哈希?

例如 UNIQUE_SALT("HelloWord", 3DES);

想法是HelloWorld不会出现在已编译的二进制文件中,只是一个哈希.

编辑:这些声明中有许多分布在大型代码库中.

小智 12

为什么不生成构建过程的哈希部分?你可以写一个简单的批处理文件来生成哈希(假设你有一个程序来做这样的事情 - 如果没有,写一个)并让它输出一个预处理器指令,如:

#define MY_HASH 123456789 
Run Code Online (Sandbox Code Playgroud)

到.h文件,然后在您的应用程序中获取#included.

  • @Ashirus嗯,我仍然认为处理它们的最好方法是集中它们,然后以某种方式生成所需的定义. (2认同)

Geo*_*che 12

使用C++ 0x,这可能是#1#2中的答案所涵盖的.

在C++ 03中,没有编译时字符串处理.使用预处理器,您无法将字符串分隔为标记,使用模板无法访问单个字符.然而,对使用C++ 0x的推测方法进行了讨论.

你可以为C++ 03做的是通过字符串传递字符串(可能使用多字符文字):

foo = hash<3DES, str<'a','b','c'> >::result;
// or:
foo = hash<3DES, str<'abc','def'> >::result;
Run Code Online (Sandbox Code Playgroud)

......或者只是将其作为预构建步骤.


mic*_*ljt 9

虽然这不是问题的正确答案,但请参阅此博客条目,以获取最多256个字符的字符串哈希函数示例,该字符串纯粹作为C宏实现:

http://lolengine.net/blog/2011/12/20/cpp-constant-string-hash

以下是博客的实际代码:

#include <string.h>
#include <stdint.h>
#include <stdio.h>

#define H1(s,i,x)   (x*65599u+(uint8_t)s[(i)<strlen(s)?strlen(s)-1-(i):strlen(s)])
#define H4(s,i,x)   H1(s,i,H1(s,i+1,H1(s,i+2,H1(s,i+3,x))))
#define H16(s,i,x)  H4(s,i,H4(s,i+4,H4(s,i+8,H4(s,i+12,x))))
#define H64(s,i,x)  H16(s,i,H16(s,i+16,H16(s,i+32,H16(s,i+48,x))))
#define H256(s,i,x) H64(s,i,H64(s,i+64,H64(s,i+128,H64(s,i+192,x))))

#define HASH(s)    ((uint32_t)(H256(s,0,0)^(H256(s,0,0)>>16)))
Run Code Online (Sandbox Code Playgroud)

如果您提前知道只将其用于静态字符串,则可以用sizeof()替换strlen().


Edd*_*onk 6

这可以通过Boost.MPL完成,但它可能不是您所追求的哈希类型.

http://arcticinteractive.com/2009/04/18/compile-time-string-hashing-boost-mpl/