github.com/huandu/go@v0.0.0-20151114150818-04e615e41150/src/hash/fnv/fnv_test.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package fnv
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/binary"
    10  	"hash"
    11  	"testing"
    12  )
    13  
    14  type golden struct {
    15  	sum  []byte
    16  	text string
    17  }
    18  
    19  var golden32 = []golden{
    20  	{[]byte{0x81, 0x1c, 0x9d, 0xc5}, ""},
    21  	{[]byte{0x05, 0x0c, 0x5d, 0x7e}, "a"},
    22  	{[]byte{0x70, 0x77, 0x2d, 0x38}, "ab"},
    23  	{[]byte{0x43, 0x9c, 0x2f, 0x4b}, "abc"},
    24  }
    25  
    26  var golden32a = []golden{
    27  	{[]byte{0x81, 0x1c, 0x9d, 0xc5}, ""},
    28  	{[]byte{0xe4, 0x0c, 0x29, 0x2c}, "a"},
    29  	{[]byte{0x4d, 0x25, 0x05, 0xca}, "ab"},
    30  	{[]byte{0x1a, 0x47, 0xe9, 0x0b}, "abc"},
    31  }
    32  
    33  var golden64 = []golden{
    34  	{[]byte{0xcb, 0xf2, 0x9c, 0xe4, 0x84, 0x22, 0x23, 0x25}, ""},
    35  	{[]byte{0xaf, 0x63, 0xbd, 0x4c, 0x86, 0x01, 0xb7, 0xbe}, "a"},
    36  	{[]byte{0x08, 0x32, 0x67, 0x07, 0xb4, 0xeb, 0x37, 0xb8}, "ab"},
    37  	{[]byte{0xd8, 0xdc, 0xca, 0x18, 0x6b, 0xaf, 0xad, 0xcb}, "abc"},
    38  }
    39  
    40  var golden64a = []golden{
    41  	{[]byte{0xcb, 0xf2, 0x9c, 0xe4, 0x84, 0x22, 0x23, 0x25}, ""},
    42  	{[]byte{0xaf, 0x63, 0xdc, 0x4c, 0x86, 0x01, 0xec, 0x8c}, "a"},
    43  	{[]byte{0x08, 0x9c, 0x44, 0x07, 0xb5, 0x45, 0x98, 0x6a}, "ab"},
    44  	{[]byte{0xe7, 0x1f, 0xa2, 0x19, 0x05, 0x41, 0x57, 0x4b}, "abc"},
    45  }
    46  
    47  func TestGolden32(t *testing.T) {
    48  	testGolden(t, New32(), golden32)
    49  }
    50  
    51  func TestGolden32a(t *testing.T) {
    52  	testGolden(t, New32a(), golden32a)
    53  }
    54  
    55  func TestGolden64(t *testing.T) {
    56  	testGolden(t, New64(), golden64)
    57  }
    58  
    59  func TestGolden64a(t *testing.T) {
    60  	testGolden(t, New64a(), golden64a)
    61  }
    62  
    63  func testGolden(t *testing.T, hash hash.Hash, gold []golden) {
    64  	for _, g := range gold {
    65  		hash.Reset()
    66  		done, error := hash.Write([]byte(g.text))
    67  		if error != nil {
    68  			t.Fatalf("write error: %s", error)
    69  		}
    70  		if done != len(g.text) {
    71  			t.Fatalf("wrote only %d out of %d bytes", done, len(g.text))
    72  		}
    73  		if actual := hash.Sum(nil); !bytes.Equal(g.sum, actual) {
    74  			t.Errorf("hash(%q) = 0x%x want 0x%x", g.text, actual, g.sum)
    75  		}
    76  	}
    77  }
    78  
    79  func TestIntegrity32(t *testing.T) {
    80  	testIntegrity(t, New32())
    81  }
    82  
    83  func TestIntegrity32a(t *testing.T) {
    84  	testIntegrity(t, New32a())
    85  }
    86  
    87  func TestIntegrity64(t *testing.T) {
    88  	testIntegrity(t, New64())
    89  }
    90  
    91  func TestIntegrity64a(t *testing.T) {
    92  	testIntegrity(t, New64a())
    93  }
    94  
    95  func testIntegrity(t *testing.T, h hash.Hash) {
    96  	data := []byte{'1', '2', 3, 4, 5}
    97  	h.Write(data)
    98  	sum := h.Sum(nil)
    99  
   100  	if size := h.Size(); size != len(sum) {
   101  		t.Fatalf("Size()=%d but len(Sum())=%d", size, len(sum))
   102  	}
   103  
   104  	if a := h.Sum(nil); !bytes.Equal(sum, a) {
   105  		t.Fatalf("first Sum()=0x%x, second Sum()=0x%x", sum, a)
   106  	}
   107  
   108  	h.Reset()
   109  	h.Write(data)
   110  	if a := h.Sum(nil); !bytes.Equal(sum, a) {
   111  		t.Fatalf("Sum()=0x%x, but after Reset() Sum()=0x%x", sum, a)
   112  	}
   113  
   114  	h.Reset()
   115  	h.Write(data[:2])
   116  	h.Write(data[2:])
   117  	if a := h.Sum(nil); !bytes.Equal(sum, a) {
   118  		t.Fatalf("Sum()=0x%x, but with partial writes, Sum()=0x%x", sum, a)
   119  	}
   120  
   121  	switch h.Size() {
   122  	case 4:
   123  		sum32 := h.(hash.Hash32).Sum32()
   124  		if sum32 != binary.BigEndian.Uint32(sum) {
   125  			t.Fatalf("Sum()=0x%x, but Sum32()=0x%x", sum, sum32)
   126  		}
   127  	case 8:
   128  		sum64 := h.(hash.Hash64).Sum64()
   129  		if sum64 != binary.BigEndian.Uint64(sum) {
   130  			t.Fatalf("Sum()=0x%x, but Sum64()=0x%x", sum, sum64)
   131  		}
   132  	}
   133  }
   134  
   135  func BenchmarkFnv32KB(b *testing.B) {
   136  	benchmarkKB(b, New32())
   137  }
   138  
   139  func BenchmarkFnv32aKB(b *testing.B) {
   140  	benchmarkKB(b, New32a())
   141  }
   142  
   143  func BenchmarkFnv64KB(b *testing.B) {
   144  	benchmarkKB(b, New64())
   145  }
   146  
   147  func BenchmarkFnv64aKB(b *testing.B) {
   148  	benchmarkKB(b, New64a())
   149  }
   150  
   151  func benchmarkKB(b *testing.B, h hash.Hash) {
   152  	b.SetBytes(1024)
   153  	data := make([]byte, 1024)
   154  	for i := range data {
   155  		data[i] = byte(i)
   156  	}
   157  	in := make([]byte, 0, h.Size())
   158  
   159  	b.ResetTimer()
   160  	for i := 0; i < b.N; i++ {
   161  		h.Reset()
   162  		h.Write(data)
   163  		h.Sum(in)
   164  	}
   165  }