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
|
|||
|
}
|