util/crc32.go

148 lines
2.7 KiB
Go
Raw Permalink Normal View History

2021-01-09 22:59:27 +08:00
package util
import (
2024-01-23 23:02:08 +08:00
"encoding/hex"
"hash/crc32"
"io"
"os"
"path/filepath"
"strings"
2021-01-09 22:59:27 +08:00
)
2024-01-19 01:36:33 +08:00
type CRC32Result struct {
2024-01-23 23:02:08 +08:00
value uint32
err error
2024-01-19 01:36:33 +08:00
}
func (c *CRC32Result) Value() uint32 {
2024-02-19 16:46:42 +08:00
if c.err != nil {
return 0
}
2024-01-23 23:02:08 +08:00
return c.value
2024-01-19 01:36:33 +08:00
}
func (c *CRC32Result) Array() [4]byte {
2024-02-19 16:46:42 +08:00
if c.err != nil {
return [4]byte{}
}
2024-01-23 23:02:08 +08:00
return UInt32ToBytesArray(c.value)
2024-01-19 01:36:33 +08:00
}
func (c *CRC32Result) Slice() []byte {
2024-02-19 16:46:42 +08:00
if c.err != nil {
return []byte{}
}
2024-01-23 23:02:08 +08:00
return UInt32ToBytesSlice(c.value)
2024-01-19 01:36:33 +08:00
}
func (c *CRC32Result) Upper() string {
2024-02-19 16:46:42 +08:00
if c.err != nil {
return ""
}
2024-01-23 23:02:08 +08:00
return strings.ToUpper(hex.EncodeToString(c.Slice()))
2024-01-19 01:36:33 +08:00
}
func (c *CRC32Result) Lower() string {
2024-02-19 16:46:42 +08:00
if c.err != nil {
return ""
}
2024-01-23 23:02:08 +08:00
return strings.ToLower(hex.EncodeToString(c.Slice()))
2024-01-19 01:36:33 +08:00
}
func (c *CRC32Result) Error() error {
2024-01-23 23:02:08 +08:00
return c.err
2024-01-19 01:36:33 +08:00
}
func NewCRC32Result(result uint32, err error) *CRC32Result {
2024-01-23 23:02:08 +08:00
return &CRC32Result{
value: result,
err: err,
}
2024-01-19 01:36:33 +08:00
}
type CRC32 struct{}
2024-01-19 10:48:33 +08:00
func NewCRC32() *CRC32 {
2024-01-23 23:02:08 +08:00
return &CRC32{}
2024-01-19 01:36:33 +08:00
}
2024-01-19 10:48:33 +08:00
func (c *CRC32) FromReader(r io.Reader) *CRC32Result {
2024-01-23 23:02:08 +08:00
return c.FromReaderChunk(r, 1024*8)
2024-01-19 10:48:33 +08:00
}
2024-01-23 21:12:04 +08:00
func (c *CRC32) FromFile(filename string) *CRC32Result {
2024-01-23 23:02:08 +08:00
file, err := os.Open(filepath.Clean(filename))
if err != nil {
return NewCRC32Result(0, err)
}
defer func() {
_ = file.Close()
}()
return c.FromReader(file)
2024-01-19 01:36:33 +08:00
}
2024-01-19 10:48:33 +08:00
func (c *CRC32) FromReaderChunk(r io.Reader, chunksize int) *CRC32Result {
2024-01-23 23:02:08 +08:00
val := uint32(0)
buf := make([]byte, chunksize)
var n int
var err error
for {
n, err = r.Read(buf)
if err != nil {
if err != io.EOF {
return NewCRC32Result(0, err)
}
if n > 0 {
val = crc32.Update(val, crc32.IEEETable, buf[:n])
}
break
}
val = crc32.Update(val, crc32.IEEETable, buf[:n])
}
return NewCRC32Result(val, nil)
2024-01-19 01:36:33 +08:00
}
2024-01-23 21:12:04 +08:00
func (c *CRC32) FromFileChunk(filename string, chunksize int) *CRC32Result {
2024-01-23 23:02:08 +08:00
file, err := os.Open(filepath.Clean(filename))
if err != nil {
return NewCRC32Result(0, err)
}
defer func() {
_ = file.Close()
}()
return c.FromReaderChunk(file, chunksize)
2024-01-19 01:36:33 +08:00
}
2024-01-19 10:48:33 +08:00
func (c *CRC32) FromBytes(data []byte) *CRC32Result {
2024-01-23 23:02:08 +08:00
return NewCRC32Result(crc32.ChecksumIEEE(data), nil)
2024-01-19 01:36:33 +08:00
}
2024-01-19 10:48:33 +08:00
func (c *CRC32) FromString(data string) *CRC32Result {
2024-01-23 23:02:08 +08:00
return NewCRC32Result(crc32.ChecksumIEEE([]byte(data)), nil)
2024-01-19 01:36:33 +08:00
}
type CRC32Pip struct {
2024-01-23 23:02:08 +08:00
crc uint32
2024-01-19 01:36:33 +08:00
}
func NewCRC32Pip() *CRC32Pip {
2024-01-23 23:02:08 +08:00
return &CRC32Pip{crc: 0}
2024-01-19 01:36:33 +08:00
}
func (c *CRC32Pip) Write(data []byte) (n int, err error) {
2024-01-23 23:02:08 +08:00
c.crc = crc32.Update(c.crc, crc32.IEEETable, data)
return len(data), nil
2024-01-19 01:36:33 +08:00
}
func (c *CRC32Pip) WriteBytes(data []byte) {
2024-01-23 23:02:08 +08:00
c.crc = crc32.Update(c.crc, crc32.IEEETable, data)
2024-01-19 01:36:33 +08:00
}
func (c *CRC32Pip) WriteString(data string) {
2024-01-23 23:02:08 +08:00
c.crc = crc32.Update(c.crc, crc32.IEEETable, []byte(data))
2024-01-19 01:36:33 +08:00
}
func (c *CRC32Pip) Result() *CRC32Result {
2024-01-23 23:02:08 +08:00
return NewCRC32Result(c.crc, nil)
2021-01-09 22:59:27 +08:00
}