Pregunta

Tengo el siguiente código:

    public void AddHash( int val )
    {
        m_Hash ^= (val & 0x3FFFFFF);
        m_Hash ^= (val >> 26) & 0x3F;
    }

Me gustaría mucho saber qué diablos hace, pero estaría satisfecho de saber cómo construir un bool HasHash( int val ) Eso me dice si M_hash tiene ese número o no ...

¿algo como esto?

    public bool HasHash( int val )
    {
        return (m_Hash & val) == 0;
    }
¿Fue útil?

Solución

Editar para solucionar el error que encontró @schnaader: ¿Que hace? Este código probablemente quiere rotar val hacia la izquierda (en sentido horario) por 6 bits y forman la suma de complemento (Editar: no el producto, como había dicho antes) - el xor- de ese valor rotado y el valor actual de m_Hash para producir un nuevo m_Hash. Ese nuevo m_Hash se utilizará la próxima vez AddHash( ) se llama.

Sin embargo, el código tal como está escrito tiene un error: gira solo los 6 bits de orden de alto orden de val hacia la izquierda, dejando en su lugar los 26 bits de orden bajo de val. El código luego XORS juntos tres valores:

  1. el nuevo orden bajo (antiguo orden alto) 6 bits de val;
  2. los 26 bits originales, sin desplazarse de 26 bits de val; y
  3. el valor actual de m_Hash

Dejando el resultado en m_Hash.

¿Cómo lo hace? Puedes simplemente mapearlo y emularlo:

  1. val & 0x3FFFFFF significa extraer los 26 bits de orden bajo de val.
  2. xor esos 26 bits con el valor actual de m_Hash

  3. Ahora cambia val hacia la derecha de tal manera que los 26 bits de orden bajo dejan el extremo de orden bajo, dejando lo que solía ser los 6 bits de alto orden de val en el orden bajo 6 bits de val.

  4. Enmascarar 0x3f extraer solo esos 6 bits de orden bajo (en caso de que algunos bits extraños se cambiaran a la parte de alto orden de val).
  5. xor esos 6 bits de orden bajo con el valor actual de m_Hash para dar el nuevo m_Hash.

Usted sabe que la rotación y el servicio exclusivo son operaciones comunes para calcular un hash.

EDITAR: @Schnaader señaló el error en el código original: ese código olvidó hacer la otra pierna de la rotación: cambiando los 26 bits de orden bajo dejados por 6. Para solucionarlo, el código debería leer algo como:

public void AddHash( int val )
{
  m_Hash ^= ((val & 0x3FFFFFF) << 6);
  m_Hash ^= (val >> 26) & 0x3F;
}

En cuanto a tu HasHash( ) Función: debes saber que decir

return (m_Hash & val) == 0;

devolverá verdadero en muchas condiciones, incluidos algunas que quizás no desee. Por ejemplo, la función devolverá verdadero si m_Hash == 0xC0 y val == 0x03.

Otros consejos

Lo que hace el código

Se necesitan los últimos 26 bits de val y lo combina con m_Hash usando Xor. Después de eso, combina esto con los primeros 6 bits de val. Por lo tanto, un entero con 32 bras de longitud se reducirá a 26 bits. De acuerdo con la principio de paloma, esto es no reversible.

Función hashash

Para que no podrás crear un HasHash función incluso si solo llamó AddHash solo una vez, porque múltiples valores de entrada en val dará como resultado lo mismo m_hash valor.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top