-
Notifications
You must be signed in to change notification settings - Fork 5
/
scramble.go
56 lines (45 loc) · 1.18 KB
/
scramble.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
package kasa
import (
"bytes"
"encoding/binary"
)
// ScrambleTCP is for TCP, It writes the length in the first byte. It uses a binary buffer and writer.
func ScrambleTCP(plaintext string) []byte {
var buf bytes.Buffer
n := len(plaintext)
buf.Grow(n + 4)
// write the length as a 32-bit big-endian uint
binary.Write(&buf, binary.BigEndian, uint32(n))
key := byte(0xAB)
for i := 0; i < n; i++ {
key = plaintext[i] ^ key
if err := buf.WriteByte(key); err != nil {
klogger.Printf(err.Error())
break
}
}
return buf.Bytes()
}
// Scramble is simpler. UDP doesn't require the length header, just allocates and write to a slice.
func Scramble(plaintext string) []byte {
n := len(plaintext)
payload := make([]byte, n)
key := byte(0xAB)
for i := 0; i < n; i++ {
payload[i] = plaintext[i] ^ key
key = payload[i]
}
return payload
}
// Unscramble turns the response from the Kasa into parsable JSON
// it works in place -- be careful with your buffers
func Unscramble(ciphertext []byte) []byte {
key := byte(0xAB)
var nextKey byte
for i := 0; i < len(ciphertext); i++ {
nextKey = ciphertext[i]
ciphertext[i] = ciphertext[i] ^ key
key = nextKey
}
return ciphertext
}