123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- package crc32
- import (
- "hash"
- "sync"
- )
- const Size = 4
- const (
-
-
- IEEE = 0xedb88320
-
-
-
- Castagnoli = 0x82f63b78
-
-
-
- Koopman = 0xeb31d82e
- )
- type Table [256]uint32
- var castagnoliTable *Table
- var castagnoliTable8 *slicing8Table
- var castagnoliArchImpl bool
- var updateCastagnoli func(crc uint32, p []byte) uint32
- var castagnoliOnce sync.Once
- func castagnoliInit() {
- castagnoliTable = simpleMakeTable(Castagnoli)
- castagnoliArchImpl = archAvailableCastagnoli()
- if castagnoliArchImpl {
- archInitCastagnoli()
- updateCastagnoli = archUpdateCastagnoli
- } else {
-
- castagnoliTable8 = slicingMakeTable(Castagnoli)
- updateCastagnoli = func(crc uint32, p []byte) uint32 {
- return slicingUpdate(crc, castagnoliTable8, p)
- }
- }
- }
- var IEEETable = simpleMakeTable(IEEE)
- var ieeeTable8 *slicing8Table
- var ieeeArchImpl bool
- var updateIEEE func(crc uint32, p []byte) uint32
- var ieeeOnce sync.Once
- func ieeeInit() {
- ieeeArchImpl = archAvailableIEEE()
- if ieeeArchImpl {
- archInitIEEE()
- updateIEEE = archUpdateIEEE
- } else {
-
- ieeeTable8 = slicingMakeTable(IEEE)
- updateIEEE = func(crc uint32, p []byte) uint32 {
- return slicingUpdate(crc, ieeeTable8, p)
- }
- }
- }
- func MakeTable(poly uint32) *Table {
- switch poly {
- case IEEE:
- ieeeOnce.Do(ieeeInit)
- return IEEETable
- case Castagnoli:
- castagnoliOnce.Do(castagnoliInit)
- return castagnoliTable
- }
- return simpleMakeTable(poly)
- }
- type digest struct {
- crc uint32
- tab *Table
- }
- func New(tab *Table) hash.Hash32 {
- if tab == IEEETable {
- ieeeOnce.Do(ieeeInit)
- }
- return &digest{0, tab}
- }
- func NewIEEE() hash.Hash32 { return New(IEEETable) }
- func (d *digest) Size() int { return Size }
- func (d *digest) BlockSize() int { return 1 }
- func (d *digest) Reset() { d.crc = 0 }
- func Update(crc uint32, tab *Table, p []byte) uint32 {
- switch tab {
- case castagnoliTable:
- return updateCastagnoli(crc, p)
- case IEEETable:
-
-
- ieeeOnce.Do(ieeeInit)
- return updateIEEE(crc, p)
- default:
- return simpleUpdate(crc, tab, p)
- }
- }
- func (d *digest) Write(p []byte) (n int, err error) {
- switch d.tab {
- case castagnoliTable:
- d.crc = updateCastagnoli(d.crc, p)
- case IEEETable:
-
-
- d.crc = updateIEEE(d.crc, p)
- default:
- d.crc = simpleUpdate(d.crc, d.tab, p)
- }
- return len(p), nil
- }
- func (d *digest) Sum32() uint32 { return d.crc }
- func (d *digest) Sum(in []byte) []byte {
- s := d.Sum32()
- return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
- }
- func Checksum(data []byte, tab *Table) uint32 { return Update(0, tab, data) }
- func ChecksumIEEE(data []byte) uint32 {
- ieeeOnce.Do(ieeeInit)
- return updateIEEE(0, data)
- }
|