-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbinenc.go
54 lines (50 loc) · 1.67 KB
/
binenc.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
// Package binenc encodes and decodes strings to integer basing on a fixed strings key.
package binenc
import "errors"
// Key is used to encode and decode elements (relying on indexes).
// Key should contain a maximum of 64 strings.
type Key []string
// Encode strings into int64 basing on the key.
// Elements not containing on the key are ignored.
// Return an error if element index is greater than 63.
// Elements order is ignored: ["foo", "bar"] and ["bar", "foo"] have the same code.
func (key Key) Encode(elements []string) (int64, error) {
var res int64
// for each element
for _, element := range elements {
// find the index of the element in the key
for i, v := range key {
if element == v {
if i > 63 {
return 0, errors.New("Index to high, key should contain 64 strings or less")
}
// add to res 1 left shifted by the index
// examples:
// when i == 0: 1 << 0 -> 001 -> res += 1 (1 base2 -> 1 base10)
// when i == 2: 1 << 2 -> 100 -> res += 4 (100 base2 -> 4 base10)
res += 1 << i
break
}
}
}
return res, nil
}
// Decode strings from int64 basing on the key.
// Strings are returned in the order as they appear in the key.
func (key Key) Decode(code int64) []string {
res := []string{}
// for each item, check if the related binary is 1
// example:
// if item index (i) == 2
// check if the code third number from the right is 1:
// remove i numbers on the right then check if last numer is 1 (%2 == 1)
// examples
// when code == 0101: 0101 >> 2 -> 0001 -> add item
// when code == 1001: 1001 >> 2 -> 0010 -> continue
for i, v := range key {
if ((code >> i) % 2) == 1 {
res = append(res, v)
}
}
return res
}