|  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
73
74
75
76
77
78
79
80
81
82
83
84
85
 | package main
import (
    "bytes"
    "encoding/binary"
    "fmt"
    "hash/crc32"
)
// Packet packet message
// | 32 bit length | 16 bit version | 32 bit crc | length - 80 bit info |
type Packet struct {
    length  uint32
    version uint16
    crc32   uint32
    info    []byte
}
// Encode encode message
func (p Packet) Encode() (data []byte, err error) {
    buf := new(bytes.Buffer)
    p.length = uint32(len(p.info) + 10)
    err = binary.Write(buf, binary.LittleEndian, (uint32)(p.length))
    if err != nil {
        return
    }
    err = binary.Write(buf, binary.LittleEndian, (uint16)(p.version))
    if err != nil {
        return
    }
    // 返回使用IEEE多项式计算出的CRC-32校验和
    p.crc32 = crc32.ChecksumIEEE(p.info)
    err = binary.Write(buf, binary.LittleEndian, p.crc32)
    if err != nil {
        return
    }
    err = binary.Write(buf, binary.LittleEndian, p.info)
    if err != nil {
        return
    }
    return buf.Bytes(), nil
}
// DecodeLength decode message length
func (p *Packet) DecodeLength(data []byte) (err error) {
    //p.length = binary.LittleEndian.Uint32(data)
    buf := bytes.NewBuffer(data)
    err = binary.Read(buf, binary.LittleEndian, &(p.length))
    return
}
// Decode decode message
func (p *Packet) Decode(data []byte) (err error) {
    buf := bytes.NewBuffer(data)
    err = binary.Read(buf, binary.LittleEndian, &(p.length))
    if err != nil {
        return
    }
    err = binary.Read(buf, binary.LittleEndian, &(p.version))
    if err != nil {
        return
    }
    err = binary.Read(buf, binary.LittleEndian, &(p.crc32))
    if err != nil {
        return
    }
    p.info = buf.Bytes()
    crc := crc32.ChecksumIEEE(p.info)
    if crc != p.crc32 {
        err = fmt.Errorf("checksum of data failed")
    }
    return
}
 |