-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsax.py
55 lines (40 loc) · 1.66 KB
/
sax.py
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
import numpy as np
SAX_INITIAL_KEY = 0x28559CA0
SAX_KEY_INCREMENT = 0xCEBD531B
def uint32_to_bytes(u):
return [u & 0xff, (u >> 8) & 0xff, (u >> 16) & 0xff, (u >> 24) & 0xff]
def next_uint32(data_ptr):
return (((data_ptr[3] << 24) & 0xff000000) + ((data_ptr[2] << 16) & 0xff0000) + ((data_ptr[1] << 8) & 0xff00) + (data_ptr[0] & 0xff)) & 0xffffffff
def uint(x):
return x & 0xffffffff
def decode_sax_chunk(data_ptr, decode_code):
"""
This function decodes an 8 bytes chunk (2 x 4-byte uint32_t)
Note that due to little endian, the bytes are in different order than when used as a byte*
"""
b0 = next_uint32(data_ptr)
b0 &= 0xffffffff
b1 = next_uint32(data_ptr[4:8])
b1 &= 0xffffffff
key = SAX_INITIAL_KEY
i = 0
while i < 32:
b1 -= np.uint32(np.uint32(((decode_code[3] + np.uint32(b0 >> 5)) & 0xffffffff)) ^ np.uint32(((key + b0) & 0xffffffff)) ^ np.uint32(((decode_code[2] + b0 * 16) & 0xffffffff)))
b1 &= 0xffffffff
b0 -= np.uint32(np.uint32(((decode_code[1] + np.uint32(b1 >> 5)) & 0xffffffff)) ^ np.uint32(((key + b1) & 0xffffffff)) ^ np.uint32(((decode_code[0] + b1 * 16) & 0xffffffff)))
b0 &= 0xffffffff
key += SAX_KEY_INCREMENT
key &= 0xffffffff
i += 1
return b0, b1
def decode_sax_data(data_ptr, data_len, decode_code):
output = []
i = 0
ptr = 0
while i < (data_len >> 3): # todo: is >> 3 same as /8? can we replace i < len >> 3 with just ptr < len?
b0, b1 = decode_sax_chunk(data_ptr[ptr:], decode_code)
output.extend(uint32_to_bytes(b0))
output.extend(uint32_to_bytes(b1))
ptr += 8
i += 1
return output