Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r61889 - in sandbox/hash: boost boost/hash boost/hash/detail libs/hash/doc/html libs/hash/test
From: me22.ca+boost_at_[hidden]
Date: 2010-05-10 04:06:43


Author: smcmurray
Date: 2010-05-10 04:06:39 EDT (Mon, 10 May 2010)
New Revision: 61889
URL: http://svn.boost.org/trac/boost/changeset/61889

Log:
hash: add a generalized Adler checksum implementation
Added:
   sandbox/hash/boost/hash/adler.hpp (contents, props changed)
   sandbox/hash/boost/hash/detail/primes.hpp (contents, props changed)
   sandbox/hash/libs/hash/test/adler.cpp (contents, props changed)
Text files modified:
   sandbox/hash/boost/hash.hpp | 5 +++++
   sandbox/hash/libs/hash/doc/html/concepts.html | 7 ++++++-
   sandbox/hash/libs/hash/doc/html/introduction.html | 2 +-
   sandbox/hash/libs/hash/doc/html/performance.html | 38 ++++++++++++++++++++++----------------
   sandbox/hash/libs/hash/doc/html/quickstart.html | 34 +++++++++++++++++++++++-----------
   5 files changed, 57 insertions(+), 29 deletions(-)

Modified: sandbox/hash/boost/hash.hpp
==============================================================================
--- sandbox/hash/boost/hash.hpp (original)
+++ sandbox/hash/boost/hash.hpp 2010-05-10 04:06:39 EDT (Mon, 10 May 2010)
@@ -9,6 +9,10 @@
 #ifndef BOOST_HASH_HPP
 #define BOOST_HASH_HPP
 
+// Checksums
+#include <boost/hash/adler.hpp>
+
+// Cryptographic Hashes
 #include <boost/hash/cubehash.hpp>
 #include <boost/hash/md4.hpp>
 #include <boost/hash/md5.hpp>
@@ -16,6 +20,7 @@
 #include <boost/hash/sha1.hpp>
 #include <boost/hash/sha2.hpp>
 
+// Infrastructure
 #include <boost/hash/compute_digest.hpp>
 #include <boost/hash/digest.hpp>
 #include <boost/hash/digest_io.hpp>

Added: sandbox/hash/boost/hash/adler.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/adler.hpp 2010-05-10 04:06:39 EDT (Mon, 10 May 2010)
@@ -0,0 +1,221 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_ADLER_HPP
+#define BOOST_HASH_ADLER_HPP
+
+#include <boost/hash/detail/primes.hpp>
+#include <boost/hash/digest.hpp>
+#include <boost/hash/pack.hpp>
+#include <boost/static_assert.hpp>
+
+#include <limits>
+
+#ifdef BOOST_HASH_SHOW_PROGRESS
+#include <cstdio>
+#endif
+
+namespace boost {
+namespace hash {
+
+template <unsigned Bits>
+class basic_adler {
+ public:
+ static unsigned const value_bits = 8;
+ typedef uint_t<value_bits>::least value_type;
+
+ BOOST_STATIC_ASSERT(Bits % 2 == 0);
+ BOOST_STATIC_ASSERT(Bits >= value_bits);
+
+ static unsigned const digest_bits = Bits;
+
+ static unsigned const word_bits = Bits;
+ typedef typename uint_t<word_bits>::least word_type;
+
+ typedef boost::array<word_type, 2> state_type;
+
+ typedef hash::digest<digest_bits> digest_type;
+
+ static word_type const modulo = detail::largest_prime<Bits/2>::value;
+
+ public:
+ basic_adler() { reset(); }
+ void reset() { state_[0] = 0; state_[1] = 1; }
+
+ digest_type digest() const {
+ word_type x = state_[0] << (Bits/2) | state_[1];
+ digest_type d;
+ // RFC 1950, Section 2.2 stores the ADLER-32 in big-endian
+ pack_n<stream_endian::big_bit,
+ digest_bits,
+ octet_bits>(&x, 1,
+ d.data(), digest_bits/octet_bits);
+ return d;
+ }
+
+ digest_type end_message() {
+ digest_type d = digest();
+ reset();
+ return d;
+ }
+
+ public:
+
+ basic_adler &
+ update_one(value_type x) {
+ if (Bits < 16) x %= modulo; // avoid overflow
+#ifdef BOOST_HASH_SHOW_PROGRESS
+printf("(%.4x, %.4x) + %.2x ==> ", (int)state_[0], (int)state_[1], (int)x);
+#endif
+ state_[1] = (state_[1] + x) % modulo;
+ state_[0] = (state_[0] + state_[1]) % modulo;
+#ifdef BOOST_HASH_SHOW_PROGRESS
+printf("(%.4x, %.4x) mod %.4x\n", (int)state_[0], (int)state_[1], (int)modulo);
+#endif
+ return *this;
+ }
+
+ template <typename IterT>
+ basic_adler &
+ update_n(IterT p, size_t n) {
+#ifndef BOOST_HASH_NO_OPTIMIZATION
+
+ unsigned const fast_word_bits = (word_bits < 16 ? 16 : word_bits);
+ typedef typename uint_t<fast_word_bits>::least/*fast*/ fast_word_type;
+/*
+
+Worst-case behaviour for delaying the modulo:
+- every input is 255
+- s1 and s0 start out at modulo-1
+
+So after k inputs, we have:
+- s1 = (modulo-1) + k*255
+- s0 = (modulo-1) + Sigma(i = 1 to k)[ (modulo-1) + i*255 ]
+ = (modulo-1) + k*(modulo-1) + Sigma(i = 1 to k)[ i*255 ]
+ = (k+1)*(modulo-1) + 255 * Sigma(i = 1 to k)[i]
+ = (k+1)*(modulo-1) + 255 * k*(k+1)/2
+
+And to avoid overflow we need s1, s0 <= 2**fast_word_bits - 1
+
+s1 = (modulo-1) + k*255 <= 2**fast_word_bits - 1
+ k*255 <= 2**fast_word_bits - 1 - (modulo-1)
+ k <= (2**fast_word_bits - modulo)/255
+
+Then use an overestimate for s0 to make the numbers nicer
+s0 < (k+1)*modulo + 256/2(k+1)**2 < 2**fast_word_bits
+
+Which solves as
+k < ( sqrt(512*2**fast_word_bits + modulo**2) - m - 256 )/256
+
+So then overestimating m as 2**(word_bits/2) and other safe approximations gives
+k < 2**((fast_word_bits-7)/2) - 2**((word_bits-16)/2) - 1
+
+Bits Limit
+---- -----
+8 16
+16 16
+24 240
+32 3840
+40 61440
+48 983040
+56 15728640
+64 251658240
+
+*/
+
+ unsigned const less = (1 << (fast_word_bits/2 - 8));
+ unsigned const limit = (1 << (fast_word_bits/2 - 4))
+ - (word_bits < 16 ? 0 : less);
+
+#define BOOST_HASH_ADLER_STEP \
+ { value_type x = *p++; s1 += x; s0 += s1; }
+
+#define BOOST_HASH_ADLER_8_STEPS \
+ { \
+ BOOST_HASH_ADLER_STEP BOOST_HASH_ADLER_STEP \
+ BOOST_HASH_ADLER_STEP BOOST_HASH_ADLER_STEP \
+ BOOST_HASH_ADLER_STEP BOOST_HASH_ADLER_STEP \
+ BOOST_HASH_ADLER_STEP BOOST_HASH_ADLER_STEP \
+ }
+
+ fast_word_type s0 = state_[0];
+ fast_word_type s1 = state_[1];
+
+ for ( ; n >= limit; n -= limit) {
+ unsigned m = limit;
+ for ( ; m >= 8; m -=8) {
+ BOOST_HASH_ADLER_8_STEPS
+ }
+ while (m--) {
+ BOOST_HASH_ADLER_STEP
+ }
+ s1 %= modulo;
+ s0 %= modulo;
+ }
+ for ( ; n >= 8; n -=8) {
+ BOOST_HASH_ADLER_8_STEPS
+ }
+ while (n--) {
+ BOOST_HASH_ADLER_STEP
+ }
+ s1 %= modulo;
+ s0 %= modulo;
+
+ state_[0] = s0;
+ state_[1] = s1;
+
+#else
+ while (n--) update_one(*p++);
+#endif
+ return *this;
+ }
+
+ template <typename IterT>
+ basic_adler &
+ update(IterT b, IterT e, std::random_access_iterator_tag) {
+ return update_n(b, e-b);
+ }
+ template <typename IterT, typename Category>
+ basic_adler &
+ update(IterT b, IterT e, Category) {
+ while (b != e) update_one(*b++);
+ return *this;
+ }
+ template <typename IterT>
+ basic_adler &
+ update(IterT b, IterT e) {
+ typedef typename std::iterator_traits<IterT>::iterator_category cat;
+ return update(b, e, cat());
+ }
+
+ private:
+ state_type state_;
+};
+
+template <unsigned Bits>
+struct adler {
+ private:
+ typedef basic_adler<Bits> octet_hash_type;
+ public:
+ template <unsigned value_bits>
+ struct stream_hash {
+ BOOST_STATIC_ASSERT(value_bits == 8);
+ typedef octet_hash_type type_;
+#ifdef BOOST_HASH_NO_HIDE_INTERNAL_TYPES
+ typedef type_ type;
+#else
+ struct type : type_ {};
+#endif
+ };
+ typedef typename octet_hash_type::digest_type digest_type;
+};
+
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_ADLER_HPP

Added: sandbox/hash/boost/hash/detail/primes.hpp
==============================================================================
--- (empty file)
+++ sandbox/hash/boost/hash/detail/primes.hpp 2010-05-10 04:06:39 EDT (Mon, 10 May 2010)
@@ -0,0 +1,77 @@
+
+//
+// Copyright 2010 Scott McMurray.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_HASH_DETAIL_PRIMES_HPP
+#define BOOST_HASH_DETAIL_PRIMES_HPP
+
+#include <boost/integer.hpp>
+
+namespace boost {
+namespace hash {
+namespace detail {
+
+template <int Bits>
+struct all_ones {
+ typedef typename uint_t<Bits>::least type;
+ static type const value = (type(all_ones<Bits-1>::value) << 1) | 1;
+};
+template <>
+struct all_ones<0> {
+ typedef typename uint_t<0>::least type;
+ static type const value = 0;
+};
+
+template <int Bits>
+struct largest_prime;
+
+#define BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(B, D) \
+ template <> \
+ struct largest_prime<B> { \
+ static uint_t<B>::least const value = all_ones<B>::value - D; \
+ }
+
+// http://primes.utm.edu/lists/2small/0bit.html or
+// http://www.research.att.com/~njas/sequences/A013603
+// Though those offets are from 2**b; This code is offsets from 2**b-1
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET( 2, 0);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET( 3, 0);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET( 4, 2);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET( 5, 0);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET( 6, 2);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET( 7, 0);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET( 8, 4);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET( 9, 2);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(10, 2);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(11, 8);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(12, 2);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(13, 0);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(14, 2);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(15, 18);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(16, 14);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(17, 0);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(18, 4);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(19, 0);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(20, 2);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(21, 8);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(22, 2);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(23, 14);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(24, 2);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(25, 38);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(26, 4);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(27, 38);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(28, 56);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(29, 2);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(30, 34);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(31, 0);
+BOOST_HASH_DEFINE_LARGEST_PRIME_BY_OFFSET(32, 4);
+
+} // namespace detail
+} // namespace hash
+} // namespace boost
+
+#endif // BOOST_HASH_DETAIL_PRIMES_HPP

Modified: sandbox/hash/libs/hash/doc/html/concepts.html
==============================================================================
--- sandbox/hash/libs/hash/doc/html/concepts.html (original)
+++ sandbox/hash/libs/hash/doc/html/concepts.html 2010-05-10 04:06:39 EDT (Mon, 10 May 2010)
@@ -29,6 +29,11 @@
     <TH><tt>digest_type</tt></TH>
     </TR>
     <TR>
+ <TD>&lt;boost/hash/adler.hpp&gt;</TD>
+ <TD><tt>adler&lt;<i>h</i>&gt;</tt>, with <i>h</i> in {8, 16, 24, ..., 64}</TD>
+ <TD>digest&lt;<i>h</i>&gt;</TD>
+ </TR>
+ <TR>
     <TD>&lt;boost/hash/cubehash.hpp&gt;</TD>
     <TD><tt>cubehash&lt;<i>h</i>&gt;</tt>, <tt>cubehash&lt;<i>r</i>, <i>b</i>, <i>h</i>&gt;</tt>, with <i>h</i> in {8, 16, 24, ..., 512}, <i>r</i> in {1, 2, 3, ...} (default 16), <i>b</i> in {4, 8, 12, ..., 128} (default 32)</TD>
     <TD>digest&lt;<i>h</i>&gt;</TD>
@@ -85,7 +90,7 @@
     <DD>Equivalent to <tt>{ InputIterator i = b; for (size_t j = 0; j != n; ++j) h.update_one(*i++); }</tt>
     </DL>
 
-<P>Each HashAlgorithm model provides access to all its associated StreamHash models; Those StreamHash models are generally not accessibly in other ways.
+<P>Each HashAlgorithm model provides access to all its associated StreamHash models; Those StreamHash models are generally not accessible in other ways.
 
 <P><TABLE WIDTH="100%">
 <TR>

Modified: sandbox/hash/libs/hash/doc/html/introduction.html
==============================================================================
--- sandbox/hash/libs/hash/doc/html/introduction.html (original)
+++ sandbox/hash/libs/hash/doc/html/introduction.html 2010-05-10 04:06:39 EDT (Mon, 10 May 2010)
@@ -12,7 +12,7 @@
     <DT>Preimage resistance
     <DD>Given a digest <i>D</i>, it is challenging to produce a message <i>M'</i> such that <i>D</i> = <i>H</i>(<i>M'</i>). Ideally it would be &Omega;(2<sup><i>B</i></sup>), the average complexity of a brute-force search.
     <DT>Second preimage resistance
- <DD>Given a message <i>M</i>, it should be challenging to find a different second message <i>M'</i> such that <i>H</i>(<i>M</i>) = <i>H</i>(<i>M'</i>). Ideally it would require the same as a preimage search for <i>D</i> = <i>H</i>(<i>M</i>).
+ <DD>Given a message <i>M</i>, it should be challenging to find a different second message <i>M'</i> such that <i>H</i>(<i>M</i>) = <i>H</i>(<i>M'</i>). Ideally it would require the same as a preimage search for <i>D</i> = <i>H</i>(<i>M</i>), but for many popular algorithms it's not.
     <DT>Collision resistance
     <DD>It is challenging to produce two different messages <i>M</i> and <i>M'</i> such that <i>H</i>(<i>M</i>) = <i>H</i>(<i>M'</i>). Because of the birthday paradox, ideally it would be &Omega;(2<sup><i>B</i>/2</sup>), the average complexity of a brute-force search.
     </DL>

Modified: sandbox/hash/libs/hash/doc/html/performance.html
==============================================================================
--- sandbox/hash/libs/hash/doc/html/performance.html (original)
+++ sandbox/hash/libs/hash/doc/html/performance.html 2010-05-10 04:06:39 EDT (Mon, 10 May 2010)
@@ -53,22 +53,10 @@
 <TH>-O3
 </TR>
 <TR>
-<TD>SHA-1
-<TD>32.344s
-<TD>18.512s
-<TD>16.119s
-</TR>
-<TR>
-<TD>MD5
-<TD>8.220s
-<TD>7.750s
-<TD BGCOLOR="red">7.890s
-</TR>
-<TR>
-<TD>SHA-512
-<TD>29.121s
-<TD>16.466s
-<TD BGCOLOR="red">31.011s
+<TD>Adler-32
+<TD>1.996s
+<TD BGCOLOR="pink">2.053s
+<TD BGCOLOR="pink">2.013s
 </TR>
 <TR>
 <TD>CubeHash16/32-512
@@ -82,6 +70,24 @@
 <TD BGCOLOR="red">45.487s
 <TD BGCOLOR="red">43.747s
 </TR>
+<TR>
+<TD>MD5
+<TD>8.220s
+<TD>7.750s
+<TD BGCOLOR="pink">7.890s
+</TR>
+<TR>
+<TD>SHA-1
+<TD>32.344s
+<TD>18.512s
+<TD>16.119s
+</TR>
+<TR>
+<TD>SHA-512
+<TD>29.121s
+<TD>16.466s
+<TD BGCOLOR="red">31.011s
+</TR>
 </TABLE>
 
 <H3>Try Providing Pointers for Input</H3>

Modified: sandbox/hash/libs/hash/doc/html/quickstart.html
==============================================================================
--- sandbox/hash/libs/hash/doc/html/quickstart.html (original)
+++ sandbox/hash/libs/hash/doc/html/quickstart.html 2010-05-10 04:06:39 EDT (Mon, 10 May 2010)
@@ -21,22 +21,41 @@
     <TH>Digest Bits
     <TH>HashAlgorithm Model (in <tt>boost::hash</tt>)
     <TH>Reference
+ <TH>Design Type
     <TH>Notes
     </TR>
 
     <TR>
+ <TD>Adler-<i>h</i> (<i>h</i> in {8, 16, 24, ..., 64})
+ <TD><i>h</i>
+ <TD><tt>adler&lt;<i>h</i>&gt;</tt>
+ <TD>RFC 1950
+ <TD>Checksum
+ <TD>&nbsp;
+ </TR>
+
+ <TR>
+ <TD>CubeHash-<i>h</i> (<i>h</i> in {8, 16, 24, ..., 512})
+ <TD><i>h</i>
+ <TD><tt>cubehash&lt;<i>h</i>&gt;</tt>
+ <TD>CubeHash NIST Submission
+ <TD>Cryptographic
+ <TD>SHA-3 candidate; Not yet mature.
+ </TR>
+
+ <TR>
     <TD>MD4
     <TD>128
     <TD><tt>md4</tt>
     <TD>RFC 1320
- <TD>Practical attacks exist
+ <TD ROWSPAN=2>Cryptographic
+ <TD ROWSPAN=2>Practical attacks exist
     </TR>
     <TR>
     <TD>MD5
     <TD>128
     <TD><tt>md5</tt>
     <TD>RFC 1321
- <TD>Practical attacks exist
     </TR>
 
     <TR>
@@ -44,6 +63,7 @@
     <TD>160
     <TD><tt>sha</tt>
     <TD>FIPS 180
+ <TD ROWSPAN=6>Cryptographic
     <TD>Collisions known; Repealed
     </TR>
 
@@ -77,16 +97,8 @@
     <TD><tt>sha2&lt;512&gt;</tt>
     </TR>
     
- <TR>
- <TD>CubeHash-<i>h</i> (<i>h</i> in {8, 16, 24, ..., 512})
- <TD><i>h</i>
- <TD><tt>cubehash&lt;<i>h</i>&gt;</tt>
- <TD>CubeHash NIST Submission
- <TD>SHA-3 candidate; Suggest waiting for further cryptanalysis
- </TR>
-
     </TABLE>
-If you need security against a malicious adversary, <tt>sha2&lt;<i>h</i>&gt;</tt> is, as of 2010, the recommended choice. If not, then MD5 is a popular choice and is much faster than any of the SHAs.
+If you need security against a malicious adversary, <tt>sha2&lt;<i>h</i>&gt;</tt> is, as of 2010, the recommended choice. If not, then two popular choices are <tt>crc&lt;<i>h</i>&gt;</tt> for checksums and <tt>md5</tt> for fingerprinting.
 
 <LI>With the chosen <i>HashAlgorithm</i>, call the <tt>boost::hash::compute_digest&lt;<i>HashAlgorithm</i>&gt;</tt> function, passing it an input range (such as a container). That will return the digest as an object of type <tt><i>HashAlgorithm</i>::digest_type</tt>.
 

Added: sandbox/hash/libs/hash/test/adler.cpp
==============================================================================
--- (empty file)
+++ sandbox/hash/libs/hash/test/adler.cpp 2010-05-10 04:06:39 EDT (Mon, 10 May 2010)
@@ -0,0 +1,151 @@
+
+#include <boost/hash/adler.hpp>
+#include <boost/hash/compute_digest.hpp>
+#include <boost/hash/detail/primes.hpp>
+#include <boost/hash/digest_io.hpp>
+#include <boost/static_assert.hpp>
+
+#include <iostream>
+#include <string>
+
+#include <cassert>
+
+namespace primes_check {
+ using boost::hash::detail::largest_prime;
+
+ BOOST_STATIC_ASSERT(largest_prime< 2>::value == 3);
+ BOOST_STATIC_ASSERT(largest_prime< 3>::value == 7);
+ BOOST_STATIC_ASSERT(largest_prime< 4>::value == 13);
+ BOOST_STATIC_ASSERT(largest_prime< 5>::value == 31);
+ BOOST_STATIC_ASSERT(largest_prime< 6>::value == 61);
+ BOOST_STATIC_ASSERT(largest_prime< 7>::value == 127);
+ BOOST_STATIC_ASSERT(largest_prime< 8>::value == 251);
+ BOOST_STATIC_ASSERT(largest_prime< 9>::value == 509);
+ BOOST_STATIC_ASSERT(largest_prime<10>::value == 1021);
+ BOOST_STATIC_ASSERT(largest_prime<11>::value == 2039);
+ BOOST_STATIC_ASSERT(largest_prime<12>::value == 4093);
+ BOOST_STATIC_ASSERT(largest_prime<13>::value == 8191);
+ BOOST_STATIC_ASSERT(largest_prime<14>::value == 16381);
+ BOOST_STATIC_ASSERT(largest_prime<15>::value == 32749);
+ BOOST_STATIC_ASSERT(largest_prime<16>::value == 65521);
+
+ BOOST_STATIC_ASSERT(largest_prime<17>::value == 131071);
+ BOOST_STATIC_ASSERT(largest_prime<18>::value == 262139);
+ BOOST_STATIC_ASSERT(largest_prime<19>::value == 524287);
+ BOOST_STATIC_ASSERT(largest_prime<20>::value == 1048573);
+ BOOST_STATIC_ASSERT(largest_prime<21>::value == 2097143);
+ BOOST_STATIC_ASSERT(largest_prime<22>::value == 4194301);
+ BOOST_STATIC_ASSERT(largest_prime<23>::value == 8388593);
+ BOOST_STATIC_ASSERT(largest_prime<24>::value == 16777213);
+ BOOST_STATIC_ASSERT(largest_prime<25>::value == 33554393);
+ BOOST_STATIC_ASSERT(largest_prime<26>::value == 67108859);
+ BOOST_STATIC_ASSERT(largest_prime<27>::value == 134217689);
+ BOOST_STATIC_ASSERT(largest_prime<28>::value == 268435399);
+ BOOST_STATIC_ASSERT(largest_prime<29>::value == 536870909);
+ BOOST_STATIC_ASSERT(largest_prime<30>::value == 1073741789);
+ BOOST_STATIC_ASSERT(largest_prime<31>::value == 2147483647);
+ BOOST_STATIC_ASSERT(largest_prime<32>::value == 4294967291);
+
+}
+
+void test32() {
+ typedef boost::hash::adler<32> HASH;
+ using boost::hash::compute_digest;
+
+ {
+ HASH::digest_type d = compute_digest<HASH>("\x2");
+ std::cout << d << "\n";
+ assert(d == "00030003");
+ }
+
+ {
+ HASH::digest_type d = compute_digest<HASH>("\x2\x4");
+ std::cout << d << "\n";
+ assert(d == "000a0007");
+ }
+
+ // Messages from MD4/MD5 test vectors
+
+ {
+ HASH::digest_type d = compute_digest<HASH>("");
+ std::cout << d << "\n";
+ assert(d == "00000001");
+ }
+
+ // All with 1 MiB or less fo input checked against
+ // http://hash.online-convert.com/adler32-generator
+
+ {
+ HASH::digest_type d = compute_digest<HASH>("a");
+ std::cout << d << "\n";
+ assert(d == "00620062");
+ }
+
+ {
+ HASH::digest_type d = compute_digest<HASH>("abc");
+ std::cout << d << "\n";
+ assert(d == "024d0127");
+ }
+
+ {
+ HASH::digest_type d = compute_digest<HASH>("message digest");
+ std::cout << d << "\n";
+ assert(d == "29750586");
+ }
+
+ {
+ HASH::digest_type d = compute_digest<HASH>("abcdefghijklmnopqrstuvwxyz");
+ std::cout << d << "\n";
+ assert(d == "90860b20");
+ }
+
+ {
+ HASH::digest_type d = compute_digest<HASH>("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
+ std::cout << d << "\n";
+ assert(d == "8adb150c");
+ }
+
+ {
+ HASH::digest_type d = compute_digest<HASH>("12345678901234567890123456789012345678901234567890123456789012345678901234567890");
+ std::cout << d << "\n";
+ assert(d == "97b61069");
+ }
+
+#ifndef BOOST_HASH_SHOW_PROGRESS
+ {
+ HASH::stream_hash<8>::type sh;
+ for (unsigned i = 0; i < 1000000; ++i) sh.update_one('a');
+ HASH::digest_type d = sh.end_message();
+ std::cout << d << "\n";
+ assert(d == "15d870f9");
+ }
+
+ {
+ HASH::stream_hash<8>::type sh;
+ std::string s(1000, 'a');
+ for (unsigned i = 0; i < 1000000; ++i) sh.update_n(s.data(), s.size());
+ HASH::digest_type d = sh.end_message();
+ std::cout << d << "\n";
+ assert(d == "bbc26298");
+ }
+
+#ifndef QUICK
+ {
+ HASH::stream_hash<8>::type sh;
+ for (unsigned i = 0; i < 1000000000; ++i) sh.update_one('a');
+ HASH::digest_type d = sh.end_message();
+ std::cout << d << "\n";
+ assert(d == "bbc26298");
+ }
+#endif // QUICK
+#endif
+
+}
+
+int main() {
+ using namespace boost::hash;
+
+ test32();
+
+}
+


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk