造轮子 Jsxbin Tools

前言

这个故事还得从一只蝙蝠说起(大雾

因为要弄一个总结某一节网课的重难点的视频,想弄个好(傻)看(气)的片头的我重新捡起来万年不动的 AE。在制作的过程中又遇到了蛋疼的英文脚本不能在中文版 AE 上良好运行的问题(因为脚本的表达式是英文的,但中文版 AE 却是中文的)。虽然说可以一个个去替换表达式里的英文,但遇上表达式多一些的脚本就很烦了。于是催生出了“弄一个自动汉化脚本工具”的想法。因为脚本大多为jsxbin的加密格式,不能直接使用(其实也行的,后面会提到),因此需要将其解码为jsx格式。在 GitHub 上找了找,发现只有一个数年前的项目jsxbin-to-jsx-converter和有关jsxbin加密方式的文章。虽然现成的项目能用到是能用,但既然都找到了分析jsxbin格式的文章了,不如就用 C++ 造一个轮子吧ο(=•ω<=)ρ⌒☆

JSXBIN 格式的分析

此处的内容基本都来自这一篇文章[1],有兴趣深挖的可以去看看原文。以下内容为阅读过程中整理的笔记

文件的头部

  1. JSXBIN 文件头部通常会有一个固定的字符串@JSXBIN@ES@2.0@。这个没啥用,在需要转换为 JSX 文件的时候需要将其删去。
  2. MyBByB分别表示文件内容的开头和结尾

文件的加密方式

虽然 Adobe 网站上给出的说法是

1
The .jsxbin files are compiled JavaScript; they are in binary format so the source code is not exposed…

但从实际内容上来看,感觉更加偏向于Base64加密这种类型。

字母

单个字母[a-z]被换成了j[B-Za][A-Z]被换成了i[B-Za]。这种替换规则可以用下表来表示

小写字母替换结果大写字母替换结果
ajBAiB
bjCBiC
cjDCiD
djEDiE
ejFEiF
fjGFiG
gjHGiH
hjIHiI
ijJIiJ
jjKJiK
kjLKiL
ljMLiM
mjNMiN
njONiO
ojPOiP
pjQPiQ
qjRQiR
rjSRiS
sjTSiT
tjUTiU
ujVUiV
vjWViW
wjXWiX
xjYXiY
yjZYiZ
zjaZia

除了上面所示的转换方法外,它还具有一个标记了字母数量的前导值,例如a的前导值(字母计数器值)为B,而aa的前导值则为C

上表可以用来表示文件中的变量名、函数名等,而对于字符串类型的数据,则会在前导值前加入一个标识符Fe,用来表示跟在它后面的内容是字符串的一部分。例如zzlwd可以被表示为FjajajMjXjE,而字符串"zzlwd"则会被表示为FeFjajajMjXjE

特殊字符

特殊字符可以用下表来表示(均为半角)

特殊字符(string)含义(看看就好了)替换结果
“ ”空格hA
双引号hC
单引号hH
&hG
\反斜杠ic
:冒号ha
.hO
破折号hN
_下划线if
?问号hf
^上标ie
`反单引号ja
~波浪线je
´Accent AigulU
+加号hL
*星号hK
#井号hD
%百分号hF
/斜杠hP
|jc
(左括号hI
)右括号jJ
>大于号hc
<小于号he

(说起来全角字符应该如何处理…我看完文章后再试试看。)

数字

数字和包含数字的字符串可以用下表表示

数字替换结果数字(string)替换结果
0d (dA – 未经证实)“0”hQ
1dB“1”hR
2dC“2”hS
3dD“3”hT
4dE“4”hU
5dF“5”hV
6dG“6”hW
7dH“7”hX
8dI“8”hY
9dJ“9”hZ
10dK“10”hRhQ
11dL“11”hRhR
12dM“12”hRhS
13dN“13”hRhT
14dO“14”hRhU
15dP“15”hRhV
16dQ“16”hRhW
17dR“17”hRhX
18dS“18”hRhY
19dT“19”hRhZ
20dU“20”hShQ
21dV“21”hShR
22dW“22”hShS
23dX“23”hShT
24dY“24”hShU
25dZ“25”hShV
26dga“26”hShW
27dgb“27”hShX
28dgc“28”hShY
29dgd“29”hShZ
30dge“30”hThQ
31dgf“31”hThR
32dhA“32”hThS
33dhB“33”hThT

※上表仅仅表示单个数字或数字字符串的转换结果,不包含计数器的。

对于一个单纯的数字字符串,其转换方式和单纯的字母字符串一样,都是[计数器][替换结果]。例如“114514”可以表示为FeGhRhRhUhVhRhUFe表示字符串,G为长度计数器值)。

而对于114514这种纯粹的数字,其本身起着类似于计数器的作用,并且被表示为dgiwhe

计数器

image-20200427191746154

下面这个是数值转换的一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>
#include <string>
using namespace std;

static string ToNumberSystem26(int n) {
//s 为前缀,s2 为数字计算结果,s1 为进位次数 Counter 的符号化;
string s = "d", s1 = "", s2 = "";
if (n < 26)
s += (char)(n + 65);
else {
map<int, char> Number = {

};
int Counter = ((n - 20) / 12);
Counter += 1;
//用于统计计数器值的字符数;
//但不确定这玩意到底能不能多于两个;
int i = 0;
while (Counter > 0) {
if (i < 3) {
int m = Counter % 20;
if (m == 0)
m = 20;
s1 = (char)(m + 102) + s1;
Counter = ((Counter - m) / 20);
i++;
}
else
throw "数值溢出!";
}
while (n >= 26) {
int m = n % 12;
int mm = m;
if (m < 8)
m += 4;
else
m -= 8;
if (m < 6)
s2 = (char)(m + 65);
else
s2 = (char)(m + 91);
n = (n - mm) / 12;
}
s = s + s1 + s2;
}
return s;
}

字符计数器

如上图所示 (

行计数器

[等待更新…]


Jsxbin Tools 编写过程留下的笔记

[等待更新…]


参考来源


  1. JSXBIN-反转二进制文件类型 ↩︎