前言
前面 学了 aandroid cocoscreator 热更新 超详细篇(五)
这章 主要学习 cocoscreator 构建后 jsc 与js 文件 之间相互转化(加解密)并实际测试.
可以配置cocoscreator热更新使用
1: 准备
win7 64位
cocoscreator2.0.10 (新版本如 2.4.7应该也是可以的)
2:创建个cocoscreator helloworld工程,并构建
构建完后 在 build\jsb-link\src (这里选择是link 模板) 有3个jsc文件,在build\jsb-link\js backups (useful for debugging) 有这3个的未加密的原文件
这里主要用到 xxtea加解密算法 压缩用的是gzip,下图是引用了别人的
这里自己用go写了小工具
主要代码如下
//eh create
package mainimport ("bytes""compress/gzip""github.com/xxtea/xxtea-go/xxtea""io""io/ioutil""log""os""path""path/filepath""strconv"
)func main() {var strkey stringvar deensign uint8 //-s 1bit 0 解密 1 加密 2bit 0 无解压或加压 1 需要解压或压缩var filename stringvar outputpath string //简化到了,直接输出到当前目录//decodeencodejsc -fif len(os.Args)&1 != 1 {log.Printf("eg:decode decodeencodejsc -s 0 -k 123456 -f 1.jsc " +"encode decodeencodejsc -s 1 -k 123456 -f 1.js ")return}for i := 1; i < len(os.Args); i += 2 {switch os.Args[i] {case "-s":if tflag, ef := strconv.Atoi(os.Args[i+1]); ef == nil {deensign = uint8(tflag)if deensign > 3 {log.Printf("-s params(1bit 0 解密 1 加密 2bit 0 无解压或加压 1 需要解压或压缩) ")}deensign &= 3} else {log.Printf("-s params is error!")return}case "-k":strkey = os.Args[i+1]case "-f":filename = os.Args[i+1]case "-p"://这个参数暂时没用到outputpath = os.Args[i+1]println("%v", outputpath)default:log.Printf("params is error")return}}//strkey = "dc6c9a10-42bb-4f"//decode unzip
// filename = "tmp/settings.jsc"//filename = "zip/settings.jsc"
// deensign = 2//encode zip//filename = "enzip/settings.js"//deensign = 3//jsc 352 byte js 453 byteif len(filename) < 4 || len(strkey) < 4 { //|| len(outputpath) < 1log.Printf("check params is error!")return}cfgpath, _ := filepath.Abs(filepath.Dir(os.Args[0]))absolutepathname := path.Join(cfgpath, filename)cfg, err := os.Open(absolutepathname)if err != nil {log.Printf("can't find ", filename)return}data, err := ioutil.ReadAll(cfg)if err != nil {cfg.Close()return}cfg.Close()if deensign&1 == 0 { //decode 解密//*.jsctarfile := absolutepathname[:len(absolutepathname)-4]decodedata := xxtea.Decrypt(data, []byte(strkey))if deensign&2 > 0 { //解压if nlen, tdata := fungzip(decodedata); nlen > 0 {decodedata = make([]byte, nlen)copy(decodedata, tdata)} else {log.Printf("fungzip fail %v", absolutepathname)return}}writefile(tarfile+".js", decodedata)} else { //encode 加密//*.jstarfile := absolutepathname[:len(absolutepathname)-3]decodedata := dataif deensign&2 > 0 { //加压if nlen, tdata := fgzip(data); nlen > 0 {decodedata = make([]byte, nlen)copy(decodedata, tdata)} else {log.Printf("fgzip fail %v", absolutepathname)return}}decodedata = xxtea.Encrypt(decodedata, []byte(strkey))writefile(tarfile+".jsc", decodedata)}
}func checkFileIsExist(filename string) bool {var exist = trueif _, err := os.Stat(filename); os.IsNotExist(err) {exist = false}return exist
}//31 139 8 //0-2
// 0 0 0 0 0 0 (6个0) //3-8
//10 141 144 75 111 (9-13)
//194 48 16 132 255 139 (14-19)
func fungzip(data []byte) (int32, []byte) {b := new(bytes.Buffer)// Test NewReader.in := bytes.NewReader(data)r2, err := gzip.NewReader(in)if err != nil {log.Printf("ungzip error=%v", err)return 0, []byte{}}defer r2.Close()b.Reset()//n, err := io.Copy(b, r2)n, err := io.Copy(b, r2)if err != nil {//t.Errorf("%s: io.Copy: %v want %v", tt.desc, err, tt.err)log.Printf("ungzip error=%v", err)return 0, []byte{}}return int32(n), b.Bytes()
}//func fgzip(data []byte, filename string) (int32, []byte) {
func fgzip(data []byte) (int32, []byte) {//buf := new(bytes.Buffer)w := gzip.NewWriter(buf)n0 := buf.Len()if n0 != 0 {//t.Fatalf("buffer size = %d before writes; want 0", n0)log.Printf("fgzip buffer size = %d before writes; want 0", n0)defer w.Close()return 0, []byte{}}w1, e1 := w.Write(data)if e1 != nil {log.Printf("fgzip buffer size = %d before writes; want %v", w1, n0)defer w.Close()return 0, []byte{}}// log.Printf("write date len=%v", w1)n1 := buf.Len()if err := w.Flush(); err != nil {log.Printf("fgzip err=%v", err.Error())defer w.Close()return 0, []byte{}}n2 := buf.Len()if n2 == n1 {log.Printf("no data after first flush")defer w.Close()return 0, []byte{}}w.Close()n3 := buf.Len()// log.Printf("write date len=%v", n3)return int32(n3), buf.Bytes()//
}func writefile(filename string, filedata []byte) bool {if f, e := os.Create(filename); e == nil {f.Write(filedata)f.Close()return true}return false
}
假如编译的执行文件叫 decodeencodejsc
1:解密
执行文件跟jsc 文件放同目录下
1> 不需要解压
decodeencodejsc -s 0 -k 密钥 -f 1.jsc
2> 需要解压
decodeencodejsc -s 2 -k 密钥 -f 1.jsc
同目录下生成1.js
2:加密
执行文件跟js 文件放同目录下
1> 不需要压缩
decodeencodejsc -s 1 -k 密钥 -f 1.js
2> 需要压缩
decodeencodejsc -s 3 -k 密钥 -f 1.js
同目录下生成1.jsc
3:测试
1:把cocoscreator生成jsc解密
执行后得到,结果是OK的
2:把js 加密
怎么测试呢,把生成jsc文件替换掉 build\jsb-link\src 的,再打包成apk 运行就知道了
4:查看引擎的xxtea zip 代码
万一XXTEA zip 版本跟引擎的不一致呢,会不会出错
这里告诉大家引擎版本的的原文件位置(构建后,以android为例用as打开)
如需工程代码后续在上传,执行文件下载地址(x86_64架构下 windows7 centos7 执行文件)
https://download.csdn.net/download/yunteng521/74707369
重复下 使用说明
假如执行文件叫 decodeencodejsc
1:解密
执行文件跟jsc 文件放同目录下
1> 不需要解压
decodeencodejsc -s 0 -k 密钥 -f 1.jsc
2> 需要解压
decodeencodejsc -s 2 -k 密钥 -f 1.jsc
同目录下生成1.js
2:加密
执行文件跟js 文件放同目录下
1> 不需要压缩
decodeencodejsc -s 1 -k 密钥 -f 1.js
2> 需要压缩
decodeencodejsc -s 3 -k 密钥 -f 1.js
同目录下生成1.jsc