簡體   English   中英

避免在哈希函數中嚴格違反別名

[英]Avoiding strict aliasing violation in hash function

我如何避免嚴格違反別名規則,嘗試修改sha256函數的char*結果。

計算哈希值:

std::string sha = sha256("some text");
const char* sha_result = sha.c_str();
unsigned long* mod_args = reinterpret_cast<unsigned long*>(sha_result);

比得到2個64位:

unsigned long a = mod_args[1] ^ mod_args[3] ^ mod_args[5] ^ mod_args[7];
unsigned long b = mod_args[0] ^ mod_args[2] ^ mod_args[4] ^ mod_args[6]; 

比通過concat獲得結果有兩個方面:

unsigned long long result = (((unsigned long long)a) << 32) | b;

聽起來令人沮喪,但唯一真正可移植,符合標准和有效的方法是通過memcpy() 使用reinterpret_cast違反了嚴格的別名規則,並且當您從未寫入的成員中讀取時,使用union (通常建議)會觸發未定義的行為。

但是,由於大多數編譯器都會優化memcpy()調用,所以這並不像聽起來那樣令人沮喪。

例如,下面的代碼帶有兩個memcpy()

char* foo() {
  char* sha = sha256("some text");
  unsigned int mod_args[8];
  memcpy(mod_args, sha, sizeof(mod_args));
  mod_args[5] = 0;
  memcpy(sha, mod_args, sizeof(mod_args));
  return sha;
}

產生以下優化的裝配:

foo():                                # @foo()
        pushq   %rax
        movl    $.L.str, %edi
        callq   sha256(char const*)
        movl    $0, 20(%rax)
        popq    %rdx
        retq

很容易看到,那里沒有memcpy() -值被“就地”修改了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM