-
Notifications
You must be signed in to change notification settings - Fork 0
/
crc16.go
72 lines (54 loc) · 1.79 KB
/
crc16.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Copyright 2023 The FIT SDK for 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.
package crc16
import (
"github.com/muktihari/fit/kit/hash"
)
// Table is [16]uint16
type Table [16]uint16
const (
Size = 2 // An uint16 requires 2 bytes to be represented in its binary form.
)
var fitTable = &Table{
0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400,
}
// MakeFitTable is the table defined in [https://developer.garmin.com/fit/protocol]
func MakeFitTable() *Table { return fitTable }
// New creates a new hash.Hash16 computing the CRC-16 checksum using the polynomial represented by the Table.
// The computing algorithm is using FIT algorithm defined in [https://developer.garmin.com/fit/protocol].
// Its Sum method will lay the value out in big-endian byte order.
func New(table *Table) hash.Hash16 {
return &crc16{table: table}
}
type crc16 struct {
table *Table
crc uint16
}
func (c *crc16) Write(p []byte) (n int, err error) {
for _, b := range p {
c.crc = c.compute(c.crc, b)
}
return len(p), nil
}
func (c *crc16) Sum(b []byte) []byte {
s := c.Sum16()
return append(b, byte(s>>8), byte(s))
}
func (c *crc16) Reset() { c.crc = 0 }
func (c *crc16) Size() int { return Size }
func (c *crc16) BlockSize() int { return 1 }
func (c *crc16) Sum16() uint16 { return c.crc }
func (c *crc16) compute(crc uint16, b byte) uint16 {
var tmp uint16
// compute checksum of lower four bits of byte
tmp = c.table[crc&0xF]
crc = (crc >> 4) & 0x0FFF
crc = crc ^ tmp ^ c.table[b&0xF]
// now compute checksum of upper four bits of byte
tmp = c.table[crc&0xF]
crc = (crc >> 4) & 0x0FFF
crc = crc ^ tmp ^ c.table[(b>>4)&0xF]
return crc
}