-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathsmazz_test.go
128 lines (112 loc) · 7.13 KB
/
smazz_test.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright 2017 Blues Inc. All rights reserved.
// Use of this source code is governed by licenses granted by the
// copyright holder including that found in the LICENSE file.
package notelib
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
)
const verboseSmazzTest = false
type smazzTest struct {
name string
uncompressed []byte
compressed []byte
crc16 uint16
}
var smazzTests = []smazzTest{
{
name: "test-null",
uncompressed: []byte{},
compressed: []byte{},
crc16: 0x0000,
},
{
name: "test-grow",
uncompressed: []byte("AAAAAaBBBBBbCCCCCcDDDDDdEEEEEeFFFFFf"),
compressed: []byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x61, 0x42, 0x42, 0x42, 0x42, 0x42, 0x62, 0x43, 0x43, 0x43, 0x43, 0x43, 0x63, 0x44, 0x44, 0x44, 0x44, 0x44, 0x64, 0x45, 0x45, 0x45, 0x45, 0x45, 0x65, 0x46, 0x46, 0x46, 0x46, 0x46, 0x66},
crc16: 0x794F,
},
{
name: "test1",
uncompressed: []byte(`{"p":"net.ozzie.ray:test","s":"my device","k":"NOTE-LORA,"v":"1.2.3","o":""}`),
compressed: []byte{0x00, 0x00, 0x1B, 0x46, 0x8F, 0x1A, 0x25, 0x25, 0x94, 0x2A, 0xBA, 0x24, 0x36, 0xB6, 0xC5, 0x92, 0x1E, 0x46, 0xE4, 0x26, 0xB8, 0xE6, 0x89, 0x92, 0x16, 0x46, 0xFF, 0x04, 0x4E, 0x4F, 0x54, 0x45, 0x28, 0xFF, 0x04, 0x4C, 0x4F, 0x52, 0x41, 0x5D, 0x46, 0xC2, 0xC3, 0x05, 0x92, 0x1A, 0x46, 0x01},
crc16: 0x0CB6,
},
{
name: "test2",
uncompressed: []byte(`{"minutes":12,"v_min":12.1,"v_max":12.1,"v_chg":12.1,"i_min":12.1,"i_max":12.1,"i_chg":12.1,"p_min":12.1,"p_max":12.1,"p_chg":12.1}`),
compressed: []byte{0x00, 0x00, 0x81, 0x20, 0xB6, 0x1E, 0x3A, 0x5D, 0xEC, 0x42, 0x5D, 0xED, 0x42, 0x5D, 0x66, 0x8E, 0x42, 0x50, 0xEC, 0x42, 0x50, 0xED, 0x42, 0x50, 0x66, 0x8E, 0x42, 0x57, 0xEC, 0x42, 0x57, 0xED, 0x42, 0x57, 0x66, 0x8E, 0x42, 0x33},
crc16: 0xC1A7,
},
{
name: "test3",
uncompressed: []byte(`{"status":"0","motion":12,"seconds":14,"time":14,"dop":12.1,"voltage":12.1,"daily_charging_mins":14,"distance":14.1,"bearing":14.1,"velocity":14.1,"temperature":12.1,"humidity":12.1,"pressure":14.1,"total":12,"count":12,"sensor":"12","usv":14.1,"cpm":12.1,"cpm_secs":12,"cpm_count":14,"journey":14,"jcount":12,"button":true,"inside_fence":true,"usb":true,"charging":true}`),
compressed: []byte{0x00, 0x00, 0xEE, 0xF2, 0x45, 0x54, 0xD3, 0x9A, 0x3A, 0x5A, 0xCF, 0xAF, 0xEF, 0x3C, 0x5B, 0xD5, 0x10, 0x3C, 0x4B, 0x1A, 0x1B, 0x42, 0x5D, 0xFB, 0xC7, 0xE3, 0x42, 0x4B, 0x0C, 0xDE, 0x24, 0x66, 0xC8, 0xF3, 0x99, 0xEC, 0x1E, 0x3C, 0x4B, 0x14, 0xC5, 0xAC, 0x89, 0x43, 0x49, 0x10, 0xB4, 0x99, 0x43, 0x5D, 0x10, 0x17, 0x1A, 0x0E, 0xBD, 0x24, 0x43, 0x5B, 0xBF, 0xCA, 0xBA, 0xFA, 0xAA, 0x42, 0x4F, 0xF6, 0xDB, 0xBD, 0x24, 0x42, 0x57, 0xAA, 0xF7, 0x20, 0xAA, 0x43, 0x5B, 0xD3, 0xB5, 0x3A, 0x4A, 0x1A, 0xD4, 0x1F, 0x3A, 0x5A, 0xA8, 0x1E, 0xB3, 0x46, 0x03, 0x04, 0x92, 0xF2, 0x21, 0x43, 0x4A, 0xF4, 0x42, 0x4A, 0xF4, 0x76, 0x82, 0x3A, 0x4A, 0xF4, 0x66, 0x1A, 0xD4, 0x1F, 0x3C, 0x51, 0xD0, 0xF5, 0x24, 0x3C, 0x51, 0xB7, 0xD4, 0x1F, 0x3A, 0x49, 0x20, 0x1F, 0xB9, 0x19, 0x38, 0x50, 0xF9, 0xDB, 0x10, 0x69, 0xA8, 0x89, 0x38, 0x5C, 0x1E, 0x0D, 0x38, 0x4A, 0xC8, 0xF3, 0x99, 0x38, 0x33},
crc16: 0x9650,
},
{
name: "test4",
uncompressed: []byte(`{"voltage":12.1,"temperature":14.1,"humidity":14.1,"pressure":14.1,"motion":12,"count":14}`),
compressed: []byte{0x00, 0x00, 0xF0, 0xC7, 0xE3, 0x42, 0x5B, 0xBF, 0xCA, 0xBA, 0xFA, 0xAA, 0x43, 0x4F, 0xF6, 0xDB, 0xBD, 0x24, 0x43, 0x57, 0xAA, 0xF7, 0x20, 0xAA, 0x43, 0x54, 0xD3, 0x9A, 0x3A, 0x4A, 0x1A, 0xD4, 0x1F, 0x3C, 0x33},
crc16: 0xC51C,
},
{
name: "test5",
uncompressed: []byte(`{"sensor":"12","pm01_0":14.1,"pm02_5":14.1,"pm10_0":14.1,"pm01_0_rstd":12.1,"pm02_5_rstd":12.1,"pm10_0_rstd":12.1,"c00_30":12,"c00_50":12,"c01_00":12,"c02_50":12,"c05_00":12,"c10_00":12,"pm01_0cf1":14.1,"pm02_5cf1":14.1,"pm10_0cf1":14.1,"csamples":12,"csecs":12,"voltage":12.1,"temperature":14.1,"humidity":14.1,"pressure":14.1,"charging":true,"usb":true,"indoors":true,"motion":12,"cpm":12.1,"cpm_count":14,"usv":12.1}`),
compressed: []byte{0x00, 0x00, 0xB1, 0xF9, 0xB3, 0x46, 0x03, 0x04, 0x92, 0xF4, 0x02, 0x03, 0x29, 0x02, 0x43, 0x57, 0x18, 0x02, 0x04, 0x29, 0x07, 0x43, 0x57, 0x18, 0x03, 0x02, 0x29, 0x02, 0x43, 0x57, 0x18, 0x02, 0x03, 0x29, 0x02, 0x29, 0xD2, 0x1F, 0x0F, 0x42, 0x57, 0x18, 0x02, 0x04, 0x29, 0x07, 0x29, 0xD2, 0x1F, 0x0F, 0x42, 0x57, 0x18, 0x03, 0x02, 0x29, 0x02, 0x29, 0xD2, 0x1F, 0x0F, 0x42, 0x4A, 0x02, 0x02, 0x29, 0x05, 0x02, 0x3A, 0x4A, 0x02, 0x02, 0x29, 0x07, 0x02, 0x3A, 0x4A, 0x02, 0x03, 0x29, 0x02, 0x02, 0x3A, 0x4A, 0x02, 0x04, 0x29, 0x07, 0x02, 0x3A, 0x4A, 0x02, 0x07, 0x29, 0x02, 0x02, 0x3A, 0x4A, 0x03, 0x02, 0x29, 0x02, 0x02, 0x3A, 0x57, 0x18, 0x02, 0x03, 0x29, 0x02, 0x0E, 0x11, 0x03, 0x43, 0x57, 0x18, 0x02, 0x04, 0x29, 0x07, 0x0E, 0x11, 0x03, 0x43, 0x57, 0x18, 0x03, 0x02, 0x29, 0x02, 0x0E, 0x11, 0x03, 0x43, 0x4A, 0xBE, 0x18, 0x1B, 0xC1, 0x1E, 0x3A, 0x4A, 0x8B, 0x1E, 0x3A, 0x5D, 0xFB, 0xC7, 0xE3, 0x42, 0x5B, 0xBF, 0xCA, 0xBA, 0xFA, 0xAA, 0x43, 0x4F, 0xF6, 0xDB, 0xBD, 0x24, 0x43, 0x57, 0xAA, 0xF7, 0x20, 0xAA, 0x43, 0x4A, 0xC8, 0xF3, 0x99, 0x38, 0x5C, 0x1E, 0x0D, 0x38, 0x50, 0xB2, 0x1A, 0xB3, 0x1E, 0x38, 0x54, 0xD3, 0x9A, 0x3A, 0x4A, 0xF4, 0x42, 0x4A, 0xF4, 0x66, 0x1A, 0xD4, 0x1F, 0x3C, 0x5C, 0x1E, 0x21, 0x42, 0x33},
crc16: 0xA926,
},
{
name: "unicode",
uncompressed: []byte(`{"サッポロシチュウオウク":"*","_note":"0"}`),
compressed: []byte{0x00, 0x00, 0xff, 0x21, 0xe3, 0x82, 0xb5, 0xe3, 0x83, 0x83, 0xe3, 0x83, 0x9d, 0xe3, 0x83, 0xad, 0xe3, 0x82, 0xb7, 0xe3, 0x83, 0x81, 0xe3, 0x83, 0xa5, 0xe3, 0x82, 0xa6, 0xe3, 0x82, 0xaa, 0xe3, 0x82, 0xa6, 0xe3, 0x82, 0xaf, 0x46, 0xfe, 0x2a, 0x92, 0x71, 0xd3, 0x10, 0x45, 0x33},
crc16: 0xC293,
},
}
func TestSmazz(t *testing.T) {
ctx := Smazz(SmazzCodeTemplate)
for _, test := range smazzTests {
compressed, err := ctx.Encode(nil, test.uncompressed)
require.NoError(t, err)
isUncompressed := ""
if len(test.uncompressed) == 0 || compressed[0] != 0 {
isUncompressed = "(would have grown)"
}
decompressed, err := ctx.Decode(nil, compressed)
require.NoError(t, err)
pct := float64(0)
if len(test.uncompressed) > 0 {
pct = float64(len(test.uncompressed)-len(compressed)) * 100.0 / float64(len(test.uncompressed))
}
testDecompressed, err := ctx.Decode(nil, test.compressed)
require.NoError(t, err)
if verboseSmazzTest {
fmt.Printf("smazz_test name:%s inp:%d enc:%d dec:%d pct:%f %s\n", test.name, len(test.uncompressed), len(compressed), len(decompressed), pct, isUncompressed)
}
require.Equal(t, Crc16(test.uncompressed), test.crc16)
require.Equal(t, decompressed, test.uncompressed)
require.Equal(t, len(compressed), len(test.compressed))
require.Equal(t, decompressed, test.uncompressed)
require.Equal(t, compressed, test.compressed)
require.Equal(t, decompressed, testDecompressed)
}
}
// CRC-16 calculation using IBM polynomial
// x^16 + x^15 + x^2 + 1 (0xA001)
// Initial value: 0
func Crc16(data []byte) uint16 {
size := len(data)
var crc uint16
for i := 0; i < size; i++ {
crc ^= uint16(data[i])
for k := 0; k < 8; k++ {
if (crc & 1) != 0 {
crc = (crc >> 1) ^ 0xA001
} else {
crc = crc >> 1
}
}
}
return crc
}