Usando PowerPC de 64 bits e gostaria de resultado hash de 32 bits em uma sequência de strings não contíguas.
Haverá alguma perda na qualidade do hash se eu estiver fazendo o hash de uma sequência de strings não contíguas usando XXH64 e simplesmente passando o resultado de cada hash como a semente da próxima chamada XXH64? Além disso, eu consideraria apenas os 32 bits inferiores do resultado final como meu valor hash de 32 bits único final que representa a sequência de strings.
Os hashes subsequentes que devem ser iguais serão executados exatamente na mesma sequência de strings. Em outras palavras, não preciso que o hash final desta sequência "STRING1", "STRING2" seja igual ao hash final de "STRIN", "G1STRING2"
Meu código atual usa CRC32 e faz o acima (passando o resultado intermediário para a próxima string como uma semente)
Obrigado.
Haverá alguma perda na qualidade do hash se eu estiver fazendo o hash de uma sequência de strings não contíguas usando XXH64 e simplesmente passando o resultado de cada hash como a semente da próxima chamada XXH64?
É uma grande perda.
Por favor, dê uma olhada em XXH64_state_t
, XXH64_update_endian
e XXH64_digest_endian
.
Você pode ver que XXH64 usa (grava e lê) XXH64_state_t
variáveis de membro v1
, v2
, v3
, v4
, total_len
para criar o valor de hash. E o tipo desses valores é unsigned long long
( uint_64
, inteiro sem sinal de 64 bits).
Nós podemos dizer:
(1) XXH64_state
O número total de bits
(2) Se uma vez que o estado for minimizado (digerir) para um valor único de 64 bits, grande parte das informações desaparecerá.
Portanto, você não pode esperar sua suposição. Considere o uso de funções de streaming .
Conforme sugerido por @ t-mat, as funções de streaming foram projetadas exatamente para este cenário.
Suponho que você esteja preocupado com a velocidade.
Não acho que você ganharia nada passando o resultado de um hash para o próximo.
Manter um contexto de streaming realmente tem um custo, mas finalizar um hash também. Espero que a finalização do hash após alguns bytes custasse mais do que manter um contexto de streaming, onde a finalização é realizada apenas uma vez, quando XXH_digest()
é invocado.
Meu objetivo é fornecer um substituto 'imediato' para o uso do CRC32 para melhorar a velocidade, com mudança mínima de código para os muitos sites de chamada. A abordagem de streaming não é tecnicamente aplicável, porque o hash de um fluxo dividido em blocos de 10 bytes será o mesmo que o hash do mesmo fluxo dividido em blocos de 100 bytes. A 'estrutura' das strings descontíguas é relevante e deve contribuir para o resultado hash.
Esta é uma string que tem referências 'indiretas' a outras strings embutidas em locais arbitrários (apenas um nível de profundidade). Preciso fazer o hash das strings indiretas e subconjuntos da string base (sem incluir os ponteiros para as strings indiretas)
Eu vi que usar XXH64 é mais rápido em hardware de 64 bits e terá um desempenho melhor do que XXH32 - pegando 32 bits do resultado como hash.
Estou satisfeito com um nível de qualidade de hash de 32 bits, então parecia razoável colocar o hash de 32 bits das várias strings como a semente de incorporação da próxima string.
Se sua estrutura de programa existente permitir, prefira passar 64 bits entre 2 hashes consecutivos. Execute a extração de 32 bits apenas no final. Isso irá maximizar a qualidade do hash.
Você está sugerindo modificar o código para permitir uma semente de 64 bits? Atualmente, em vez de simplesmente extrair os 32 bits inferiores para semear a próxima etapa, estou xando os 32 bits superiores e os 32 inferiores juntos para que todos os 64 bits "contribuam" para o transporte de 32 bits. Infelizmente, não é viável (sem copiar os dados) acrescentar ou preceder o valor intermediário de 64 bits à próxima string, pois não tenho controle sobre esse armazenamento, ele é entregue a mim.
Não importa, vejo agora que XXH64 permite um valor de semente de 64 bits.
Comentários muito úteis
Não importa, vejo agora que XXH64 permite um valor de semente de 64 bits.