90 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2011 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.
 | |
| 
 | |
| // This file contains CRC32 algorithms that are not specific to any architecture
 | |
| // and don't use hardware acceleration.
 | |
| //
 | |
| // The simple (and slow) CRC32 implementation only uses a 256*4 bytes table.
 | |
| //
 | |
| // The slicing-by-8 algorithm is a faster implementation that uses a bigger
 | |
| // table (8*256*4 bytes).
 | |
| 
 | |
| package crc32
 | |
| 
 | |
| // simpleMakeTable allocates and constructs a Table for the specified
 | |
| // polynomial. The table is suitable for use with the simple algorithm
 | |
| // (simpleUpdate).
 | |
| func simpleMakeTable(poly uint32) *Table {
 | |
| 	t := new(Table)
 | |
| 	simplePopulateTable(poly, t)
 | |
| 	return t
 | |
| }
 | |
| 
 | |
| // simplePopulateTable constructs a Table for the specified polynomial, suitable
 | |
| // for use with simpleUpdate.
 | |
| func simplePopulateTable(poly uint32, t *Table) {
 | |
| 	for i := 0; i < 256; i++ {
 | |
| 		crc := uint32(i)
 | |
| 		for j := 0; j < 8; j++ {
 | |
| 			if crc&1 == 1 {
 | |
| 				crc = (crc >> 1) ^ poly
 | |
| 			} else {
 | |
| 				crc >>= 1
 | |
| 			}
 | |
| 		}
 | |
| 		t[i] = crc
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // simpleUpdate uses the simple algorithm to update the CRC, given a table that
 | |
| // was previously computed using simpleMakeTable.
 | |
| func simpleUpdate(crc uint32, tab *Table, p []byte) uint32 {
 | |
| 	crc = ^crc
 | |
| 	for _, v := range p {
 | |
| 		crc = tab[byte(crc)^v] ^ (crc >> 8)
 | |
| 	}
 | |
| 	return ^crc
 | |
| }
 | |
| 
 | |
| // Use slicing-by-8 when payload >= this value.
 | |
| const slicing8Cutoff = 16
 | |
| 
 | |
| // slicing8Table is array of 8 Tables, used by the slicing-by-8 algorithm.
 | |
| type slicing8Table [8]Table
 | |
| 
 | |
| // slicingMakeTable constructs a slicing8Table for the specified polynomial. The
 | |
| // table is suitable for use with the slicing-by-8 algorithm (slicingUpdate).
 | |
| func slicingMakeTable(poly uint32) *slicing8Table {
 | |
| 	t := new(slicing8Table)
 | |
| 	simplePopulateTable(poly, &t[0])
 | |
| 	for i := 0; i < 256; i++ {
 | |
| 		crc := t[0][i]
 | |
| 		for j := 1; j < 8; j++ {
 | |
| 			crc = t[0][crc&0xFF] ^ (crc >> 8)
 | |
| 			t[j][i] = crc
 | |
| 		}
 | |
| 	}
 | |
| 	return t
 | |
| }
 | |
| 
 | |
| // slicingUpdate uses the slicing-by-8 algorithm to update the CRC, given a
 | |
| // table that was previously computed using slicingMakeTable.
 | |
| func slicingUpdate(crc uint32, tab *slicing8Table, p []byte) uint32 {
 | |
| 	if len(p) >= slicing8Cutoff {
 | |
| 		crc = ^crc
 | |
| 		for len(p) > 8 {
 | |
| 			crc ^= uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24
 | |
| 			crc = tab[0][p[7]] ^ tab[1][p[6]] ^ tab[2][p[5]] ^ tab[3][p[4]] ^
 | |
| 				tab[4][crc>>24] ^ tab[5][(crc>>16)&0xFF] ^
 | |
| 				tab[6][(crc>>8)&0xFF] ^ tab[7][crc&0xFF]
 | |
| 			p = p[8:]
 | |
| 		}
 | |
| 		crc = ^crc
 | |
| 	}
 | |
| 	if len(p) == 0 {
 | |
| 		return crc
 | |
| 	}
 | |
| 	return simpleUpdate(crc, &tab[0], p)
 | |
| }
 |