...

Source file src/hash/crc32/crc32_generic.go

     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	// This file contains CRC32 algorithms that are not specific to any architecture
     6	// and don't use hardware acceleration.
     7	//
     8	// The simple (and slow) CRC32 implementation only uses a 256*4 bytes table.
     9	//
    10	// The slicing-by-8 algorithm is a faster implementation that uses a bigger
    11	// table (8*256*4 bytes).
    12	
    13	package crc32
    14	
    15	// simpleMakeTable allocates and constructs a Table for the specified
    16	// polynomial. The table is suitable for use with the simple algorithm
    17	// (simpleUpdate).
    18	func simpleMakeTable(poly uint32) *Table {
    19		t := new(Table)
    20		simplePopulateTable(poly, t)
    21		return t
    22	}
    23	
    24	// simplePopulateTable constructs a Table for the specified polynomial, suitable
    25	// for use with simpleUpdate.
    26	func simplePopulateTable(poly uint32, t *Table) {
    27		for i := 0; i < 256; i++ {
    28			crc := uint32(i)
    29			for j := 0; j < 8; j++ {
    30				if crc&1 == 1 {
    31					crc = (crc >> 1) ^ poly
    32				} else {
    33					crc >>= 1
    34				}
    35			}
    36			t[i] = crc
    37		}
    38	}
    39	
    40	// simpleUpdate uses the simple algorithm to update the CRC, given a table that
    41	// was previously computed using simpleMakeTable.
    42	func simpleUpdate(crc uint32, tab *Table, p []byte) uint32 {
    43		crc = ^crc
    44		for _, v := range p {
    45			crc = tab[byte(crc)^v] ^ (crc >> 8)
    46		}
    47		return ^crc
    48	}
    49	
    50	// Use slicing-by-8 when payload >= this value.
    51	const slicing8Cutoff = 16
    52	
    53	// slicing8Table is array of 8 Tables, used by the slicing-by-8 algorithm.
    54	type slicing8Table [8]Table
    55	
    56	// slicingMakeTable constructs a slicing8Table for the specified polynomial. The
    57	// table is suitable for use with the slicing-by-8 algorithm (slicingUpdate).
    58	func slicingMakeTable(poly uint32) *slicing8Table {
    59		t := new(slicing8Table)
    60		simplePopulateTable(poly, &t[0])
    61		for i := 0; i < 256; i++ {
    62			crc := t[0][i]
    63			for j := 1; j < 8; j++ {
    64				crc = t[0][crc&0xFF] ^ (crc >> 8)
    65				t[j][i] = crc
    66			}
    67		}
    68		return t
    69	}
    70	
    71	// slicingUpdate uses the slicing-by-8 algorithm to update the CRC, given a
    72	// table that was previously computed using slicingMakeTable.
    73	func slicingUpdate(crc uint32, tab *slicing8Table, p []byte) uint32 {
    74		if len(p) >= slicing8Cutoff {
    75			crc = ^crc
    76			for len(p) > 8 {
    77				crc ^= uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24
    78				crc = tab[0][p[7]] ^ tab[1][p[6]] ^ tab[2][p[5]] ^ tab[3][p[4]] ^
    79					tab[4][crc>>24] ^ tab[5][(crc>>16)&0xFF] ^
    80					tab[6][(crc>>8)&0xFF] ^ tab[7][crc&0xFF]
    81				p = p[8:]
    82			}
    83			crc = ^crc
    84		}
    85		if len(p) == 0 {
    86			return crc
    87		}
    88		return simpleUpdate(crc, &tab[0], p)
    89	}
    90	

View as plain text