grapeCG/Crypt/CGCrypt.go

340 lines
7.9 KiB
Go
Raw Normal View History

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