/* NAME crc.go DESCRIPTION See Readme.md AUTHOR Dan Kortschak Saxon Milton LICENSE crc.go is Copyright (C) 2018 the Australian Ocean Lab (AusOcean) It is free software: you can redistribute it and/or modify them under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with revid in gpl.txt. If not, see http://www.gnu.org/licenses. */ package psi import ( "encoding/binary" "hash/crc32" "math/bits" ) // addCrc appends a crc table to a given psi table in bytes func addCrc(out []byte) []byte { t := make([]byte, len(out)+4) copy(t, out) updateCrc(t[1:]) return t } // updateCrc updates the crc of bytes slice, writing the checksum into the last four bytes. func updateCrc(b []byte) { crc32 := crc32_Update(0xffffffff, crc32_MakeTable(bits.Reverse32(crc32.IEEE)), b[:len(b)-4]) binary.BigEndian.PutUint32(b[len(b)-4:], crc32) } func crc32_MakeTable(poly uint32) *crc32.Table { var t crc32.Table for i := range t { crc := uint32(i) << 24 for j := 0; j < 8; j++ { if crc&0x80000000 != 0 { crc = (crc << 1) ^ poly } else { crc <<= 1 } } t[i] = crc } return &t } func crc32_Update(crc uint32, tab *crc32.Table, p []byte) uint32 { for _, v := range p { crc = tab[byte(crc>>24)^v] ^ (crc << 8) } return crc }