340 lines
7.9 KiB
Go
340 lines
7.9 KiB
Go
// CrossGate加解密库,用于游戏加解密
|
||
// C语言翻译为GO语言
|
||
// version 1.0 beta
|
||
// by koangel
|
||
// email: jackliu100@gmail.com
|
||
// 2017/7/23
|
||
package CGCrypt
|
||
|
||
import (
|
||
"math"
|
||
)
|
||
|
||
/*
|
||
* used by bitstream routines
|
||
*/
|
||
var bitstream_maxbyte int
|
||
var bitstream_bitaddr int
|
||
var bitstream_buf []byte
|
||
|
||
/* initialize bitstream for output */
|
||
func initOutputBitStream(buf []byte, buflen int) {
|
||
bitstream_bitaddr = 0
|
||
bitstream_maxbyte = buflen
|
||
bitstream_buf = buf
|
||
}
|
||
|
||
/* initialize bitstream for input */
|
||
func initInputBitStream(buf []byte, buflen int) {
|
||
bitstream_bitaddr = 0
|
||
bitstream_maxbyte = buflen
|
||
bitstream_buf = buf
|
||
}
|
||
|
||
/*
|
||
* read from bit stream. used only from 1 bit to 8 bits
|
||
* this is a base routine
|
||
*/
|
||
func readInputBitStreamBody(bwidth int) uint32 {
|
||
mod := bitstream_bitaddr % 8
|
||
byteaddr := bitstream_bitaddr / 8
|
||
/* return if excess */
|
||
if byteaddr >= bitstream_maxbyte {
|
||
return 0
|
||
}
|
||
|
||
if bwidth >= 1 && bwidth <= 8 {
|
||
b1 := uint((uint(bitstream_buf[byteaddr]) & uint(saacproto_modifymask_first[mod][bwidth])) >> uint(mod))
|
||
b2 := uint((uint(bitstream_buf[byteaddr+1]) & uint(saacproto_modifymask_second[mod][bwidth])) << uint(8-mod))
|
||
bitstream_bitaddr += bwidth
|
||
return uint32(b1 | b2)
|
||
} else {
|
||
return 0
|
||
}
|
||
}
|
||
|
||
/*
|
||
* read from bit stream. used from 1 bit to 32 bits
|
||
*
|
||
*/
|
||
func readInputBitStream(bwidth int) uint32 {
|
||
if bwidth <= 0 {
|
||
return 0
|
||
} else if bwidth >= 1 && bwidth <= 8 {
|
||
return readInputBitStreamBody(bwidth)
|
||
} else if bwidth >= 9 && bwidth <= 16 {
|
||
first := readInputBitStreamBody(8)
|
||
second := readInputBitStreamBody(bwidth - 8)
|
||
return first + (second << 8)
|
||
} else if bwidth >= 17 && bwidth <= 24 {
|
||
first := readInputBitStreamBody(8)
|
||
second := readInputBitStreamBody(8)
|
||
third := readInputBitStreamBody(bwidth - 8)
|
||
return first + (second << 8) + (third << 16)
|
||
} else if bwidth >= 25 && bwidth <= 32 {
|
||
first := readInputBitStreamBody(8)
|
||
second := readInputBitStreamBody(8)
|
||
third := readInputBitStreamBody(8)
|
||
forth := readInputBitStreamBody(bwidth - 8)
|
||
return first + (second << 8) + (third << 16) + (forth << 24)
|
||
}
|
||
return 0
|
||
}
|
||
|
||
/*
|
||
* write to a bitstream. only used from 1 bit to 8 bits
|
||
* this is a base routine.
|
||
*/
|
||
func writeOutputBitStreamBody(bwidth int, b byte) int {
|
||
mod := bitstream_bitaddr % 8
|
||
byteaddr := bitstream_bitaddr / 8
|
||
/* return error if excess */
|
||
if bitstream_maxbyte <= (byteaddr + 1) {
|
||
return -1
|
||
}
|
||
bitstream_buf[byteaddr] &= byte(saacproto_modifymask_first[mod][bwidth])
|
||
bitstream_buf[byteaddr] |= byte((int(b) << uint(mod)) & saacproto_modifymask_first[mod][bwidth])
|
||
bitstream_buf[byteaddr+1] &= byte(saacproto_modifymask_second[mod][bwidth])
|
||
bitstream_buf[byteaddr+1] |= byte((int(b) >> uint(8-mod)) & saacproto_modifymask_second[mod][bwidth])
|
||
bitstream_bitaddr += bwidth
|
||
return byteaddr + 1
|
||
}
|
||
|
||
/*
|
||
* write to a bitstream. used from 1 bits to 32 bits
|
||
* returns -1 if error or buffer excession
|
||
*/
|
||
func writeOutputBitStream(bwidth int, dat uint) int {
|
||
var ret int = 0
|
||
if bwidth <= 0 {
|
||
return -1
|
||
} else if bwidth >= 1 && bwidth <= 8 {
|
||
if writeOutputBitStreamBody(bwidth, byte(dat)) < 0 {
|
||
return -1
|
||
}
|
||
} else if bwidth > 8 && bwidth <= 16 {
|
||
if writeOutputBitStreamBody(8, byte(dat&0xff)) < 0 {
|
||
return -1
|
||
}
|
||
if writeOutputBitStreamBody(bwidth-8, byte((dat>>8)&0xff)) < 0 {
|
||
return -1
|
||
}
|
||
} else if bwidth > 16 && bwidth <= 24 {
|
||
if writeOutputBitStreamBody(8, byte(dat&0xff)) < 0 {
|
||
return -1
|
||
}
|
||
if writeOutputBitStreamBody(8, byte((dat>>8)&0xff)) < 0 {
|
||
return -1
|
||
}
|
||
if writeOutputBitStreamBody(bwidth-16, byte((dat>>16)&0xff)) < 0 {
|
||
return -1
|
||
}
|
||
} else if bwidth > 24 && bwidth <= 32 {
|
||
if writeOutputBitStreamBody(8, byte(dat&0xff)) < 0 {
|
||
return -1
|
||
}
|
||
if writeOutputBitStreamBody(8, byte((dat>>8)&0xff)) < 0 {
|
||
return -1
|
||
}
|
||
if writeOutputBitStreamBody(8, byte((dat>>16)&0xff)) < 0 {
|
||
return -1
|
||
}
|
||
if writeOutputBitStreamBody(bwidth-24, byte((dat>>24)&0xff)) < 0 {
|
||
return -1
|
||
}
|
||
} else {
|
||
return -1
|
||
}
|
||
return ret
|
||
}
|
||
|
||
func Encode64(in []byte) []byte {
|
||
var i int
|
||
var use_bytes int
|
||
var address int = 0
|
||
len := len(in)
|
||
out := make([]byte, len)
|
||
out[0] = 0
|
||
for i = 0; ; i += 3 {
|
||
var in1 byte
|
||
var in2 byte
|
||
var in3 byte
|
||
var out1 byte
|
||
var out2 byte
|
||
var out3 byte
|
||
var out4 byte
|
||
if i >= len {
|
||
break
|
||
}
|
||
|
||
if i >= (len - 1) { /* the last letter ( to be thrown away ) */
|
||
in1 = in[i] & 0xff
|
||
in2 = 0
|
||
in3 = 0
|
||
use_bytes = 2
|
||
} else if i >= (len - 2) { /* the last 2 letters ( process only 1 byte)*/
|
||
in1 = in[i] & 0xff
|
||
in2 = in[i+1] & 0xff
|
||
in3 = 0
|
||
use_bytes = 3
|
||
} else { /* there are more or equal than 3 letters */
|
||
in1 = in[i] & 0xff
|
||
in2 = in[i+1] & 0xff
|
||
in3 = in[i+2] & 0xff
|
||
use_bytes = 4
|
||
}
|
||
out1 = ((in1 & 0xfc) >> 2) & 0x3f
|
||
out2 = ((in1 & 0x03) << 4) | (((in2 & 0xf0) >> 4) & 0x0f)
|
||
out3 = ((in2 & 0x0f) << 2) | (((in3 & 0xc0) >> 6) & 0x03)
|
||
out4 = (in3 & 0x3f)
|
||
if use_bytes >= 2 {
|
||
out[address] = base64_charset[out1]
|
||
address++
|
||
out[address] = base64_charset[out2]
|
||
address++
|
||
out[address] = 0
|
||
}
|
||
if use_bytes >= 3 {
|
||
out[address] = base64_charset[out3]
|
||
address++
|
||
out[address] = 0
|
||
}
|
||
if use_bytes >= 4 {
|
||
out[address] = base64_charset[out4]
|
||
address++
|
||
out[address] = 0
|
||
}
|
||
}
|
||
|
||
return out
|
||
}
|
||
|
||
func Decode64(in []byte) []byte {
|
||
var in1 byte
|
||
var in2 byte
|
||
var in3 byte
|
||
var in4 byte
|
||
var out1 byte
|
||
var out2 byte
|
||
var out3 byte
|
||
var use_bytes int
|
||
var address int = 0
|
||
|
||
len := len(in)
|
||
out := make([]byte, len)
|
||
var i int
|
||
for i = 0; ; i += 4 {
|
||
if in[i] == 0 {
|
||
break
|
||
} else if in[i+1] == 0 { /* the last letter */
|
||
break
|
||
} else if in[i+2] == 0 { /* the last 2 letters */
|
||
in1 = base64_reversecharset[in[i]]
|
||
in2 = base64_reversecharset[in[i+1]]
|
||
in3 = 0
|
||
in4 = 0
|
||
use_bytes = 1
|
||
} else if in[i+3] == 0 { /* the last 3 letters */
|
||
in1 = base64_reversecharset[in[i]]
|
||
in2 = base64_reversecharset[in[i+1]]
|
||
in3 = base64_reversecharset[in[i+2]]
|
||
in4 = 0
|
||
use_bytes = 2
|
||
} else { /* process 4 letters */
|
||
in1 = base64_reversecharset[in[i]]
|
||
in2 = base64_reversecharset[in[i+1]]
|
||
in3 = base64_reversecharset[in[i+2]]
|
||
in4 = base64_reversecharset[in[i+3]]
|
||
use_bytes = 3
|
||
}
|
||
out1 = (in1 << 2) | (((in2 & 0x30) >> 4) & 0x0f)
|
||
out2 = ((in2 & 0x0f) << 4) | (((in3 & 0x3c) >> 2) & 0x0f)
|
||
out3 = ((in3 & 0x03) << 6) | (in4 & 0x3f)
|
||
if use_bytes >= 1 {
|
||
out[address] = out1
|
||
address++
|
||
}
|
||
if use_bytes >= 2 {
|
||
out[address] = out2
|
||
address++
|
||
}
|
||
if use_bytes >= 3 {
|
||
out[address] = out3
|
||
address++
|
||
}
|
||
if use_bytes != 3 {
|
||
break
|
||
}
|
||
}
|
||
|
||
return out
|
||
}
|
||
|
||
func abs(val int) int {
|
||
return int(math.Abs(float64(val)))
|
||
}
|
||
|
||
func jDecode(src []byte, key int) (decoded []byte, decodedlen int) {
|
||
decoded = make([]byte, len(src))
|
||
var sum byte = 0
|
||
var i int
|
||
var srclen = len(src)
|
||
decodedlen = srclen - 1
|
||
if decodedlen == 0 {
|
||
return /* return error if length is 0 */
|
||
}
|
||
sum = src[abs(key%(decodedlen))]
|
||
for i = 0; i < srclen; i++ {
|
||
if abs((key % (decodedlen))) > i {
|
||
decoded[i] = src[i] - byte(int(sum)*int((i*i)%3))
|
||
}
|
||
if abs((key % (decodedlen))) < i {
|
||
decoded[i-1] = src[i] - byte(int(sum)*int((i*i)%7))
|
||
}
|
||
}
|
||
for i = 0; i < decodedlen; i++ {
|
||
if ((key % 7) == (i % 5)) || ((key % 2) == (i % 2)) {
|
||
decoded[i] = ^decoded[i]
|
||
}
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
func jEncode(src []byte, key int, maxencodedlen int) (encoded []byte, encodedlen int) {
|
||
var sum byte = 0
|
||
var i int
|
||
srclen := len(src)
|
||
encoded = make([]byte, srclen)
|
||
encodedlen = srclen
|
||
if srclen+1 > maxencodedlen {
|
||
encodedlen = maxencodedlen
|
||
for i = 0; i < encodedlen; i++ {
|
||
encoded[i] = src[i]
|
||
}
|
||
}
|
||
if srclen+1 <= maxencodedlen {
|
||
encodedlen = srclen + 1
|
||
for i = 0; i < srclen; i++ {
|
||
sum = sum + src[i]
|
||
if ((key % 7) == (i % 5)) || ((key % 2) == (i % 2)) {
|
||
src[i] = ^src[i]
|
||
}
|
||
}
|
||
for i = 0; i < encodedlen; i++ {
|
||
if abs((key % srclen)) > i {
|
||
encoded[i] = src[i] + byte(int(sum)*int((i*i)%3))
|
||
}
|
||
|
||
if abs((key % srclen)) == i {
|
||
encoded[i] = sum
|
||
}
|
||
if abs((key % srclen)) < i {
|
||
encoded[i] = src[i-1] + byte(int(sum)*int((i*i)%7))
|
||
}
|
||
}
|
||
}
|
||
|
||
return
|
||
}
|