Skip to content

Commit

Permalink
Merge pull request #99 from spiral/crc32_insteadof_crc8
Browse files Browse the repository at this point in the history
Replace CRC8 with CRC32
  • Loading branch information
rustatian authored Dec 11, 2020
2 parents bb875c7 + 1266d06 commit 14dd9ca
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 93 deletions.
35 changes: 0 additions & 35 deletions crc8.go

This file was deleted.

79 changes: 29 additions & 50 deletions frame.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package goridge

import "hash/crc32"

const FRAME_OPTIONS_MAX_SIZE = 40 //nolint:stylecheck,golint
const WORD = 4 //nolint:stylecheck,golint

Expand All @@ -14,34 +16,37 @@ type Frame struct {

// ReadHeader reads only header, without payload
func ReadHeader(data []byte) *Frame {
_ = data[7]
_ = data[11]
return &Frame{
header: data[:8],
header: data[:12],
payload: nil,
}
}

func ReadFrame(data []byte) *Frame {
_ = data[0]
opt := data[0] & 0x0F
// if more than 2, that we have options
if opt > 2 {
// if more than 3, that we have options
if opt > 3 {
return &Frame{
header: data[:opt*WORD],
payload: data[opt*WORD:],
}
}

// no options
return &Frame{
header: data[:8],
payload: data[8:],
f := &Frame{
header: data[:12],
payload: data[12:],
}
f.header[10] = 0
f.header[11] = 0

return f
}

func NewFrame() *Frame {
f := &Frame{
header: make([]byte, 8),
header: make([]byte, 12),
payload: make([]byte, 0, 100),
}
// set default header len (2)
Expand Down Expand Up @@ -99,7 +104,7 @@ func (f *Frame) incrementHL() {
}
func (f *Frame) defaultHL() {
_ = f.header[0]
f.writeHl(2)
f.writeHl(3)
}

// Flags is full 1st byte
Expand All @@ -125,7 +130,7 @@ func (f *Frame) WriteOptions(options ...uint32) {
}

hl := f.readHL()
// check before writing. we can't handle more than 15*4 bytes of HL (2 for header and 12 for options)
// check before writing. we can't handle more than 15*4 bytes of HL (3 for header and 12 for options)
if hl == 15 {
panic("header len could not be more than 15")
}
Expand All @@ -148,18 +153,18 @@ func (f *Frame) AppendOptions(opts []byte) {
}

// last byte after main header and first options byte
const lb = 8
const lb = 12

// f.readHL() - 2 needed to know actual options size
// we know, that 2 WORDS is minimal header len
// extra WORDS will add extra 32bits to the options (4 bytes)
func (f *Frame) ReadOptions() []uint32 {
// we can read options, if there are no options
if f.readHL() <= 2 {
if f.readHL() <= 3 {
return nil
}
// Get the options len
optionLen := f.readHL() - 2 // 2 is the default
optionLen := f.readHL() - 3 // 3 is the default
// slice in place
options := make([]uint32, 0, optionLen)

Expand Down Expand Up @@ -197,49 +202,23 @@ func (f *Frame) WritePayloadLen(len uint32) {

// Calculating CRC and writing it to the 6th byte (7th reserved)
func (f *Frame) WriteCRC() {
_ = f.header[7]
crc := byte(0)
hl := f.readHL()
// write CRC with options
if f.readHL() > 2 {
for i := byte(0); i < hl*WORD; i++ {
crc = lookupTable[crc^f.header[i]]
}
f.header[6] = crc
return
}

for i := 0; i < 6; i++ {
crc = lookupTable[crc^f.header[i]]
}
// 6 7 8 9 bytes
// 10, 11 reserved
_ = f.header[9]

f.header[6] = crc
crc := crc32.ChecksumIEEE(f.header[:6])
f.header[6] = byte(crc)
f.header[7] = byte(crc >> 8)
f.header[8] = byte(crc >> 16)
f.header[9] = byte(crc >> 24)
}

// Reading info from 6th byte and verifying it with calculated in-place. Should be equal.
// If not - drop the frame as incorrect.
func (f *Frame) VerifyCRC() bool {
_ = f.header[7]
crc := byte(0)
hl := f.readHL()
_ = f.header[9]

if hl > 2 {
for i := byte(0); i < hl*WORD; i++ {
// to verify, we are skipping the CRC field itself
if i == 6 {
data := 0 ^ crc
crc = lookupTable[data]
continue
}
crc = lookupTable[f.header[i]^crc]
}
return crc == f.header[6]
}

for i := 0; i < 6; i++ {
crc = lookupTable[f.header[i]^crc]
}
return crc == f.header[6]
return crc32.ChecksumIEEE(f.header[:6]) == uint32(f.header[6])|uint32(f.header[7])<<8|uint32(f.header[8])<<16|uint32(f.header[9])<<24
}

// Bytes returns header with payload
Expand Down
6 changes: 4 additions & 2 deletions frame_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package goridge

import (
"hash/crc32"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -93,11 +94,11 @@ func TestFrame_Bytes(t *testing.T) {
assert.Equal(t, []uint32{323423432}, rf.ReadOptions())
}

func BenchmarkCRC8(b *testing.B) {
func BenchmarkCRC32(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
res := crc8([]byte("hello world"))
res := crc32.ChecksumIEEE([]byte{'t', 't', 'b', 'u', '6', '1', 'g', 'h', 'r', 't'})
_ = res
}
}
Expand All @@ -107,6 +108,7 @@ func BenchmarkFrame_CRC(b *testing.B) {
nf.WriteVersion(VERSION_1)
nf.WriteFlags(CONTROL, CODEC_GOB)
nf.WritePayloadLen(uint32(len([]byte(TestPayload))))
nf.WriteOptions(1000, 1000, 1000, 1000, 1000, 1000)

b.ResetTimer()
b.ReportAllocs()
Expand Down
6 changes: 3 additions & 3 deletions pipe.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func (rl *PipeRelay) Send(frame *Frame) error {
func (rl *PipeRelay) Receive(frame *Frame) error {
const op = errors.Op("pipes frame receive")
// header bytes
hb := make([]byte, 8, 8)
hb := make([]byte, 12, 12)
_, err := rl.in.Read(hb)
if err != nil {
return errors.E(op, err)
Expand All @@ -40,9 +40,9 @@ func (rl *PipeRelay) Receive(frame *Frame) error {
// Read frame header
header := ReadHeader(hb)
// we have options
if header.readHL() > 2 {
if header.readHL() > 3 {
// we should read the options
optsLen := (header.readHL() - 2) * WORD
optsLen := (header.readHL() - 3) * WORD
opts := make([]byte, optsLen)
_, err = rl.in.Read(opts)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions socket.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (rl *SocketRelay) Send(frame *Frame) error {
func (rl *SocketRelay) Receive(frame *Frame) error {
const op = errors.Op("pipes frame receive")
// header bytes
hb := make([]byte, 8, 8)
hb := make([]byte, 12, 12)
_, err := rl.rwc.Read(hb)
if err != nil {
return errors.E(op, err)
Expand All @@ -39,9 +39,9 @@ func (rl *SocketRelay) Receive(frame *Frame) error {
// Read frame header
header := ReadHeader(hb)
// we have options
if header.readHL() > 2 {
if header.readHL() > 3 {
// we should read the options
optsLen := (header.readHL() - 2) * WORD
optsLen := (header.readHL() - 3) * WORD
opts := make([]byte, optsLen)
_, err = rl.rwc.Read(opts)
if err != nil {
Expand Down

0 comments on commit 14dd9ca

Please sign in to comment.