Added CRC algos
parent
7f90da765e
commit
f5ce7276bd
@ -0,0 +1,62 @@
|
||||
// Package crc16 implements the 16-bit cyclic redundancy check, or CRC-16,
|
||||
// checksum. See http://en.wikipedia.org/wiki/Cyclic_redundancy_check for
|
||||
// information.
|
||||
package crc16
|
||||
|
||||
// Predefined polynomnials
|
||||
const (
|
||||
// Used by X.25, V.41, HDLC FCS, XMODEM, Bluetooth, PACTOR, SD, ...
|
||||
CCITT = 0x8408
|
||||
)
|
||||
|
||||
// Table is a 256-word table representing the polynomial for efficient processing.
|
||||
type Table [256]uint16
|
||||
|
||||
var (
|
||||
CCITTTable = makeTable(CCITT)
|
||||
)
|
||||
|
||||
// MakeTable returns the Table constructed from the specified polynomial.
|
||||
func MakeTable(poly uint16) *Table {
|
||||
return makeTable(poly)
|
||||
}
|
||||
|
||||
// makeTable returns the Table constructed from the specified polynomial.
|
||||
func makeTable(poly uint16) *Table {
|
||||
t := new(Table)
|
||||
for i := 0; i < 256; i++ {
|
||||
crc := uint16(i)
|
||||
for j := 0; j < 8; j++ {
|
||||
if crc&1 == 1 {
|
||||
crc = (crc >> 1) ^ poly
|
||||
} else {
|
||||
crc >>= 1
|
||||
}
|
||||
}
|
||||
t[i] = crc
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
// Update returns the result of adding the bytes in p to the crc.
|
||||
func Update(crc uint16, tab *Table, p []byte) uint16 {
|
||||
return update(crc, tab, p)
|
||||
}
|
||||
|
||||
func update(crc uint16, tab *Table, p []byte) uint16 {
|
||||
crc = ^crc
|
||||
for _, v := range p {
|
||||
crc = tab[byte(crc)^v] ^ (crc >> 8)
|
||||
}
|
||||
return ^crc
|
||||
}
|
||||
|
||||
// Checksum returns the CRC-16 checksum of data using the polynomial represented by the Table.
|
||||
func Checksum(data []byte, tab *Table) uint16 {
|
||||
return Update(0, tab, data)
|
||||
}
|
||||
|
||||
// ChecksumCCITT returns the CRC-16 checksum of data using the CCITT polynomial.
|
||||
func ChecksumCCITT(data []byte) uint16 {
|
||||
return update(0, CCITTTable, data)
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
// Package quadres_16_7 implements the quadratic residue (16, 7, 6) parity check.
|
||||
package quadres_16_7
|
||||
|
||||
import "github.com/pd0mz/go-dmr/bit"
|
||||
|
||||
var (
|
||||
validDataParities = [128]bit.Bits{}
|
||||
)
|
||||
|
||||
type Codeword struct {
|
||||
Data bit.Bits
|
||||
Parity bit.Bits
|
||||
}
|
||||
|
||||
func NewCodeword(bits bit.Bits) *Codeword {
|
||||
if len(bits) < 16 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &Codeword{
|
||||
Data: bits[:7],
|
||||
Parity: bits[7:16],
|
||||
}
|
||||
}
|
||||
|
||||
func ParityBits(bits bit.Bits) bit.Bits {
|
||||
parity := make(bit.Bits, 9)
|
||||
// Multiplying the generator matrix with the given data bits.
|
||||
// See DMR AI spec. page 134.
|
||||
parity[0] = bits[1] ^ bits[2] ^ bits[3] ^ bits[4]
|
||||
parity[1] = bits[2] ^ bits[3] ^ bits[4] ^ bits[5]
|
||||
parity[2] = bits[0] ^ bits[3] ^ bits[4] ^ bits[5] ^ bits[6]
|
||||
parity[3] = bits[2] ^ bits[3] ^ bits[5] ^ bits[6]
|
||||
parity[4] = bits[1] ^ bits[2] ^ bits[6]
|
||||
parity[5] = bits[0] ^ bits[1] ^ bits[4]
|
||||
parity[6] = bits[0] ^ bits[1] ^ bits[2] ^ bits[5]
|
||||
parity[7] = bits[0] ^ bits[1] ^ bits[2] ^ bits[3] ^ bits[6]
|
||||
parity[8] = bits[0] ^ bits[2] ^ bits[4] ^ bits[5] ^ bits[6]
|
||||
return parity
|
||||
}
|
||||
|
||||
func Check(bits bit.Bits) bool {
|
||||
codeword := NewCodeword(bits)
|
||||
if codeword == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
var dataval uint8
|
||||
for col := uint8(0); col < 7; col++ {
|
||||
if codeword.Data[col] == 1 {
|
||||
dataval |= (1 << (7 - col))
|
||||
}
|
||||
}
|
||||
|
||||
return codeword.Parity.Equal(validDataParities[dataval])
|
||||
}
|
||||
|
||||
func init() {
|
||||
for i := byte(0); i < 128; i++ {
|
||||
bits := bit.NewBits([]byte{i})
|
||||
validDataParities[i] = ParityBits(bits)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue