[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#731330: libstdc++6: functions labelled FNV-1a in /usr/include/c++/4.7/tr1/functional_hash.h are not FNV-1a



Package: libstdc++6
Version: 4.7.2-5
Severity: minor

As far as I know, the FNV and FNV-1a algorithms process octects, i.e. unsigned
chars.  (see e.g. http://tools.ietf.org/html/draft-eastlake-fnv-03#section-2 )

The implementations in /usr/include/c++/4.7/tr1/functional_hash.h work
on chars, instead, and their output is wrong (in architectures where char is
signed) when the input byte sequence includes bytes with the MSB set.

For example
    std::tr1::_Fnv_hash_base<4>::hash("\x80", 1)
returns 83079839, instead of the correct value 2232128415.

The problem resides in the type cast:

    template<>
    struct _Fnv_hash_base<4>
    {
      template<typename _Tp>
        static size_t
        hash(const _Tp* __ptr, size_t __clength)
        {
          size_t __result = static_cast<size_t>(2166136261UL);
>>>       const char* __cptr = reinterpret_cast<const char*>(__ptr);    <<<
          for (; __clength; --__clength)
            {
              __result ^= static_cast<size_t>(*__cptr++);
              __result *= static_cast<size_t>(16777619UL);
            }
          return __result;
        }
    };

The highlighed line should read:
const unsigned char* __cptr = reinterpret_cast<const unsigned char*>(__ptr);

Since the FNV primes were carefully chosen in order to minimize
collision rates and maximize dispersion, there might be consequences in
the performance of data structures that build on tr1::hash template,
perhaps tr1::unordered_map and tr1::unordered_set.

Best regards,
        g

-- System Information:
Debian Release: 7.2
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: i386 (i686)

Kernel: Linux 3.2.0-4-686-pae (SMP w/2 CPU cores)
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)
Shell: /bin/sh linked to /bin/dash

Versions of packages libstdc++6 depends on:
ii  gcc-4.7-base       4.7.2-5
ii  libc6              2.13-38
ii  libgcc1            1:4.7.2-5
ii  multiarch-support  2.13-38

libstdc++6 recommends no packages.

libstdc++6 suggests no packages.

-- no debconf information


Reply to: