You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
1.7 KiB
94 lines
1.7 KiB
package codecs
|
|
|
|
import "math"
|
|
|
|
func Encode(str string, key string) []int32 {
|
|
v := magicEncode(str, true)
|
|
k := magicEncode(key, false)
|
|
|
|
if len(k) < 4 {
|
|
|
|
}
|
|
|
|
n := len(v) - 1
|
|
z := int(v[n])
|
|
y := int(v[0])
|
|
c := -1640531527
|
|
q := math.Floor(float64(6 + 52/(n+1)))
|
|
d := 0
|
|
var m, e, p int
|
|
|
|
for ; q > 0; q-- {
|
|
d = d + c&(-1)
|
|
e = d >> 2 & 3
|
|
|
|
for i := 0; i < n; i++ {
|
|
y = int(v[p+1])
|
|
m = z>>5 ^ y<<2
|
|
m += y>>3 ^ z<<4 ^ (d ^ y)
|
|
m += int(k[p&3^e]) ^ z
|
|
v[p] = v[p] + int32(m&(-1))
|
|
z = int(v[p])
|
|
}
|
|
|
|
y = int(v[0])
|
|
m = z>>5 ^ y<<2
|
|
m += y>>3 ^ z<<4 ^ (d ^ y)
|
|
m += int(k[p&3^e]) ^ z
|
|
v[n] = v[n] + int32(m&(0xBB390742|0x44C6F8BD))
|
|
z = int(v[n])
|
|
}
|
|
|
|
return magicDecode(v, false)
|
|
}
|
|
|
|
func magicEncode(source string, sizeOnLast bool) (result []int32) {
|
|
data := []int32(source)
|
|
dataLen := len(data)
|
|
|
|
resultLen := dataLen / 4
|
|
if sizeOnLast {
|
|
result = make([]int32, resultLen+1)
|
|
result[resultLen] = int32(dataLen)
|
|
} else {
|
|
result = make([]int32, resultLen)
|
|
}
|
|
|
|
for i := 0; i < dataLen; i += 4 {
|
|
result[i>>2] = get(data, i, dataLen) | get(data, i+1, dataLen)<<8 | get(data, i+2, dataLen)<<16 | get(data, i+3, dataLen)<<24
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func magicDecode(data []int32, sizeOnLast bool) (result []int32) {
|
|
dataLength := len(data)
|
|
|
|
c := dataLength - 1<<2
|
|
|
|
if sizeOnLast {
|
|
m := int(data[dataLength-1])
|
|
if m < c-3 || m > c {
|
|
return nil
|
|
}
|
|
c = m
|
|
}
|
|
|
|
for i := 0; i < dataLength; i++ {
|
|
result = append(result, data[i]&0xff, data[i]>>8&0xff, data[i]>>16&0xff, data[i]>>24&0xff)
|
|
}
|
|
|
|
if sizeOnLast {
|
|
return append(result, int32(c))
|
|
} else {
|
|
return result
|
|
}
|
|
}
|
|
|
|
func get(data []int32, index int, length int) int32 {
|
|
if index >= length {
|
|
return 0
|
|
} else {
|
|
return data[index]
|
|
}
|
|
}
|
|
|