Kirika/hasher/accuraterip.go
DataHoarder 514a88aec1
Some checks failed
continuous-integration/drone/push Build is failing
Update to Go 1.20
2023-04-09 13:10:30 +02:00

83 lines
2 KiB
Go

package hasher
import (
"hash"
"unsafe"
)
type accurateRipDigestV1 struct {
crc uint32
pos uint32
offset uint32
}
func NewAccurateRipV1(offset uint32) hash.Hash32 {
return &accurateRipDigestV1{0, offset + 1, offset}
}
func (d *accurateRipDigestV1) Size() int { return 4 }
func (d *accurateRipDigestV1) BlockSize() int { return 1 }
func (d *accurateRipDigestV1) Reset() { d.crc = 0; d.pos = d.offset + 1 }
func (d *accurateRipDigestV1) Sum32() uint32 { return d.crc }
func (d *accurateRipDigestV1) Sum(in []byte) []byte {
s := d.Sum32()
return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
}
func (d *accurateRipDigestV1) Write(p []byte) (n int, err error) {
numWords := uintptr(len(p)) * unsafe.Sizeof(p[0]) / unsafe.Sizeof(uint32(0))
words := unsafe.Slice((*uint32)(unsafe.Pointer(unsafe.SliceData(p))), numWords)
for _, w := range words {
//this can wrap
d.crc += d.pos * w
d.pos++
}
return len(p), nil
}
type accurateRipDigestV2 struct {
crc uint32
multiplier uint32
offset uint32
}
func NewAccurateRipV2(offset uint32) hash.Hash32 {
return &accurateRipDigestV2{0, offset + 1, offset}
}
func (d *accurateRipDigestV2) Size() int { return 4 }
func (d *accurateRipDigestV2) BlockSize() int { return 1 }
func (d *accurateRipDigestV2) Reset() { d.crc = 0; d.multiplier = d.offset + 1 }
func (d *accurateRipDigestV2) Sum32() uint32 { return d.crc }
func (d *accurateRipDigestV2) Sum(in []byte) []byte {
s := d.Sum32()
return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
}
func (d *accurateRipDigestV2) Write(p []byte) (n int, err error) {
numWords := uintptr(len(p)) * unsafe.Sizeof(p[0]) / unsafe.Sizeof(uint32(0))
words := unsafe.Slice((*uint32)(unsafe.Pointer(unsafe.SliceData(p))), numWords)
for _, w := range words {
crcNew := uint64(w) * uint64(d.multiplier)
LO := crcNew & 0xFFFFFFFF
HI := crcNew / 0x100000000
//this can wrap
d.crc += uint32(HI)
d.crc += uint32(LO)
d.multiplier++
}
return len(p), nil
}