Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
Package crc32 implements the 32-bit cyclic redundancy check, or CRC-32, checksum. See https://en.wikipedia.org/wiki/Cyclic_redundancy_check for information. Polynomials are represented in LSB-first form also known as reversed representation. See https://en.wikipedia.org/wiki/Mathematics_of_cyclic_redundancy_checks#Reversed_representations_and_reciprocal_polynomials for information.
package crc32

import (
	
	
	
	
)
The size of a CRC-32 checksum in bytes.
const Size = 4
Predefined polynomials.
IEEE is by far and away the most common CRC-32 polynomial. Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, ...
	IEEE = 0xedb88320
Castagnoli's polynomial, used in iSCSI. Has better error detection characteristics than IEEE. https://dx.doi.org/10.1109/26.231911
	Castagnoli = 0x82f63b78
Koopman's polynomial. Also has better error detection characteristics than IEEE. https://dx.doi.org/10.1109/DSN.2002.1028931
	Koopman = 0xeb31d82e
)
Table is a 256-word table representing the polynomial for efficient processing.
type Table [256]uint32
This file makes use of functions implemented in architecture-specific files. The interface that they implement is as follows: // archAvailableIEEE reports whether an architecture-specific CRC32-IEEE // algorithm is available. archAvailableIEEE() bool // archInitIEEE initializes the architecture-specific CRC3-IEEE algorithm. // It can only be called if archAvailableIEEE() returns true. archInitIEEE() // archUpdateIEEE updates the given CRC32-IEEE. It can only be called if // archInitIEEE() was previously called. archUpdateIEEE(crc uint32, p []byte) uint32 // archAvailableCastagnoli reports whether an architecture-specific // CRC32-C algorithm is available. archAvailableCastagnoli() bool // archInitCastagnoli initializes the architecture-specific CRC32-C // algorithm. It can only be called if archAvailableCastagnoli() returns // true. archInitCastagnoli() // archUpdateCastagnoli updates the given CRC32-C. It can only be called // if archInitCastagnoli() was previously called. archUpdateCastagnoli(crc uint32, p []byte) uint32
castagnoliTable points to a lazily initialized Table for the Castagnoli polynomial. MakeTable will always return this value when asked to make a Castagnoli table so we can compare against it to find when the caller is using this polynomial.
Initialize the slicing-by-8 table.
IEEETable is the table for the IEEE polynomial.
ieeeTable8 is the slicing8Table for IEEE
Initialize the slicing-by-8 table.
		ieeeTable8 = slicingMakeTable(IEEE)
		updateIEEE = func( uint32,  []byte) uint32 {
			return slicingUpdate(, ieeeTable8, )
		}
	}
}
MakeTable returns a Table constructed from the specified polynomial. The contents of this Table must not be modified.
func ( uint32) *Table {
	switch  {
	case IEEE:
		ieeeOnce.Do(ieeeInit)
		return IEEETable
	case Castagnoli:
		castagnoliOnce.Do(castagnoliInit)
		return castagnoliTable
	}
	return simpleMakeTable()
}
digest represents the partial evaluation of a checksum.
type digest struct {
	crc uint32
	tab *Table
}
New creates a new hash.Hash32 computing the CRC-32 checksum using the polynomial represented by the Table. Its Sum method will lay the value out in big-endian byte order. The returned Hash32 also implements encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to marshal and unmarshal the internal state of the hash.
func ( *Table) hash.Hash32 {
	if  == IEEETable {
		ieeeOnce.Do(ieeeInit)
	}
	return &digest{0, }
}
NewIEEE creates a new hash.Hash32 computing the CRC-32 checksum using the IEEE polynomial. Its Sum method will lay the value out in big-endian byte order. The returned Hash32 also implements encoding.BinaryMarshaler and encoding.BinaryUnmarshaler to marshal and unmarshal the internal state of the hash.
func () hash.Hash32 { return New(IEEETable) }

func ( *digest) () int { return Size }

func ( *digest) () int { return 1 }

func ( *digest) () { .crc = 0 }

const (
	magic         = "crc\x01"
	marshaledSize = len(magic) + 4 + 4
)

func ( *digest) () ([]byte, error) {
	 := make([]byte, 0, marshaledSize)
	 = append(, magic...)
	 = appendUint32(, tableSum(.tab))
	 = appendUint32(, .crc)
	return , nil
}

func ( *digest) ( []byte) error {
	if len() < len(magic) || string([:len(magic)]) != magic {
		return errors.New("hash/crc32: invalid hash state identifier")
	}
	if len() != marshaledSize {
		return errors.New("hash/crc32: invalid hash state size")
	}
	if tableSum(.tab) != readUint32([4:]) {
		return errors.New("hash/crc32: tables do not match")
	}
	.crc = readUint32([8:])
	return nil
}

func ( []byte,  uint32) []byte {
	 := [4]byte{
		byte( >> 24),
		byte( >> 16),
		byte( >> 8),
		byte(),
	}
	return append(, [:]...)
}

func ( []byte) uint32 {
	_ = [3]
	return uint32([3]) | uint32([2])<<8 | uint32([1])<<16 | uint32([0])<<24
}
Update returns the result of adding the bytes in p to the crc.
func ( uint32,  *Table,  []byte) uint32 {
	switch {
	case atomic.LoadUint32(&haveCastagnoli) != 0 &&  == castagnoliTable:
		return updateCastagnoli(, )
Unfortunately, because IEEETable is exported, IEEE may be used without a call to MakeTable. We have to make sure it gets initialized in that case.
		ieeeOnce.Do(ieeeInit)
		return updateIEEE(, )
	default:
		return simpleUpdate(, , )
	}
}

func ( *digest) ( []byte) ( int,  error) {
	switch {
	case atomic.LoadUint32(&haveCastagnoli) != 0 && .tab == castagnoliTable:
		.crc = updateCastagnoli(.crc, )
We only create digest objects through New() which takes care of initialization in this case.
		.crc = updateIEEE(.crc, )
	default:
		.crc = simpleUpdate(.crc, .tab, )
	}
	return len(), nil
}

func ( *digest) () uint32 { return .crc }

func ( *digest) ( []byte) []byte {
	 := .Sum32()
	return append(, byte(>>24), byte(>>16), byte(>>8), byte())
}
Checksum returns the CRC-32 checksum of data using the polynomial represented by the Table.
func ( []byte,  *Table) uint32 { return Update(0, , ) }
ChecksumIEEE returns the CRC-32 checksum of data using the IEEE polynomial.
func ( []byte) uint32 {
	ieeeOnce.Do(ieeeInit)
	return updateIEEE(0, )
}
tableSum returns the IEEE checksum of table t.
func ( *Table) uint32 {
	var  [1024]byte
	 := [:0]
	if  != nil {
		for ,  := range  {
			 = appendUint32(, )
		}
	}
	return ChecksumIEEE()