You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
1.6 KiB
Go
74 lines
1.6 KiB
Go
// Package quadres_16_7 implements the quadratic residue (16, 7, 6) parity check.
|
|
package quadres_16_7
|
|
|
|
import "bytes"
|
|
|
|
var (
|
|
validDataParities = [128][]byte{}
|
|
)
|
|
|
|
type Codeword struct {
|
|
Data []byte
|
|
Parity []byte
|
|
}
|
|
|
|
func NewCodeword(bits []byte) *Codeword {
|
|
if len(bits) < 16 {
|
|
return nil
|
|
}
|
|
|
|
return &Codeword{
|
|
Data: bits[:7],
|
|
Parity: bits[7:16],
|
|
}
|
|
}
|
|
|
|
func ParityBits(bits []byte) []byte {
|
|
parity := make([]byte, 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 []byte) 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 bytes.Equal(codeword.Parity, validDataParities[dataval])
|
|
}
|
|
|
|
func toBits(b byte) []byte {
|
|
var o = make([]byte, 8)
|
|
for bit, mask := 0, byte(128); bit < 8; bit, mask = bit+1, mask>>1 {
|
|
if b&mask != 0 {
|
|
o[bit] = 1
|
|
}
|
|
}
|
|
return o
|
|
}
|
|
|
|
func init() {
|
|
for i := byte(0); i < 128; i++ {
|
|
bits := toBits(i)
|
|
validDataParities[i] = ParityBits(bits)
|
|
}
|
|
}
|