Beispiel #1
0
def _Py_HashBytes(val, _len):
    if (_len == 0):
        return process_return(0)

    if (_len < _Py_HASH_CUTOFF):
        # TODO: this branch needs testing, needs a CPython setup for it!
        # /* Optimize hashing of very small strings with inline DJBX33A. */
        _hash = _Py_uhash_t(5381)  # /* DJBX33A starts with 5381 */
        for idx in range(_len):
            _hash = ((_hash << 5) + _hash) + np.uint8(grab_byte(val, idx))

        _hash ^= _len
        _hash ^= _load_hashsecret('djbx33a_suffix')
    else:
        tmp = _siphash24(types.uint64(_load_hashsecret('siphash_k0')),
                         types.uint64(_load_hashsecret('siphash_k1')),
                         val, _len)
        _hash = process_return(tmp)
    return process_return(_hash)
Beispiel #2
0
    def _siphash24(k0, k1, src, src_sz):
        b = types.uint64(src_sz) << 56
        v0 = k0 ^ types.uint64(0x736f6d6570736575)
        v1 = k1 ^ types.uint64(0x646f72616e646f6d)
        v2 = k0 ^ types.uint64(0x6c7967656e657261)
        v3 = k1 ^ types.uint64(0x7465646279746573)

        idx = 0
        while (src_sz >= 8):
            mi = grab_uint64_t(src, idx)
            idx += 1
            src_sz -= 8
            v3 ^= mi
            v0, v1, v2, v3 = _DOUBLE_ROUND(v0, v1, v2, v3)
            v0 ^= mi

        # this is the switch fallthrough:
        # https://github.com/python/cpython/blob/d1dd6be613381b996b9071443ef081de8e5f3aff/Python/pyhash.c#L390-L400    # noqa: E501
        t = types.uint64(0x0)
        boffset = idx * 8
        ohexefef = types.uint64(0xff)
        if src_sz >= 7:
            jmp = (6 * 8)
            mask = ~types.uint64(ohexefef << jmp)
            t = (t & mask) | (types.uint64(grab_byte(src, boffset + 6))
                              << jmp)
        if src_sz >= 6:
            jmp = (5 * 8)
            mask = ~types.uint64(ohexefef << jmp)
            t = (t & mask) | (types.uint64(grab_byte(src, boffset + 5))
                              << jmp)
        if src_sz >= 5:
            jmp = (4 * 8)
            mask = ~types.uint64(ohexefef << jmp)
            t = (t & mask) | (types.uint64(grab_byte(src, boffset + 4))
                              << jmp)
        if src_sz >= 4:
            t &= types.uint64(0xffffffff00000000)
            for i in range(4):
                jmp = i * 8
                mask = ~types.uint64(ohexefef << jmp)
                t = (t & mask) | (types.uint64(grab_byte(src, boffset + i))
                                  << jmp)
        if src_sz >= 3:
            jmp = (2 * 8)
            mask = ~types.uint64(ohexefef << jmp)
            t = (t & mask) | (types.uint64(grab_byte(src, boffset + 2))
                              << jmp)
        if src_sz >= 2:
            jmp = (1 * 8)
            mask = ~types.uint64(ohexefef << jmp)
            t = (t & mask) | (types.uint64(grab_byte(src, boffset + 1))
                              << jmp)
        if src_sz >= 1:
            mask = ~(ohexefef)
            t = (t & mask) | (types.uint64(grab_byte(src, boffset + 0)))

        b |= t
        v3 ^= b
        v0, v1, v2, v3 = _DOUBLE_ROUND(v0, v1, v2, v3)
        v0 ^= b
        v2 ^= ohexefef
        v0, v1, v2, v3 = _DOUBLE_ROUND(v0, v1, v2, v3)
        v0, v1, v2, v3 = _DOUBLE_ROUND(v0, v1, v2, v3)
        t = (v0 ^ v1) ^ (v2 ^ v3)
        return t