在2015/06/26的维护后算法发生变化,此算法不再适用
本文档仅供学习交流之用途,一切法律相关纠纷概不负责
这段时间研究了一下舰娘游戏中api_port的计算方法
目前得出成果如下(语言为C#)
首先是api_port核心数组:
//5,17基本不变,0,1,2,4,7,8,9,11,14,15每次更新改变,3,6,10,12,13,16至今未变
//3,6,12未曾被此方法使用过
private static long[] array = {
1912, 3185, 7519, 2139, 6887, 4131807, 8897, 1224, 6367,
1052, 13, 4992, 3791, 10, 7839, 4727, 1000, 1876153
};
一看就可以明白的辅助用的方法:
//返回0~input-1的一个随机数
private static long random( long input ) {
return (int)Math.Floor(new System.Random().NextDouble() * input);
}
//返回当前时间的10位时间戳
private static long time() {
long time = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds / 1000;
return time;
}
//返回一个数字的前四位
private static long firstFour( long input ) {
long a = long.Parse(input.ToString().Substring(0, 4));
return a;
}
然后是每次api_port更新后变化的主要来源:
//返回一个由根号13计算出来的数据串
private static long func( long input ) {
long[] arr = { 1, 7, 8, 0, 11, 4, 2, 9, 15, 14 };
return arr[input % 10];
}
其实这个方法已经经过简化,原始方法是:
string sqrt = Math.Sqrt(array[array[13]]).ToString(“f15”);
//上式结果是3.605551275463989
sqrt = sqrt.Replace(".","0");
int counter = 0;
string str = (input % 10).ToString();
while (str != sqrt.Substring(counter, 1)) {
counter++;
}
return counter;
好了,至此api_port计算所需的方法已经全部说明完毕。接下来开始解说api_port的计算方法:
public static string api_port( long member_id ) {
//5位 取值32768-65535
long part_0 = random(32768) + 32768;
//4位
long part_1 = (random(9) + 1) * 1000 + (member_id % 1000);
//14位 最重要的部分
long part_2 = (((firstFour(member_id) + 1000) * (array[5] + part_0) - time()) + (array[17] + (9 * part_0)) - member_id) * array[func(member_id)];
//4位 若array[16]一直保持不变,则取值1000-9999
long part_3 = random(9 * array[16]) + array[16];
//返回完整的api_port数据串
return string.Join("" ,
part_1.ToString(), part_2.ToString(),
part_3.ToString(), part_0.ToString()
);
}
很明显,api_port由4部分组成,而其中part2是整个api_port的核心内容。
从上述计算过程可知计算part2需要以下数据:
part_0 --> 可直接于api_port数字串中获得
member_id --> 可通过其他API获得
array[5] --> 版本更新后需计算
array[17] --> 版本更新后需计算
time --> 可通过抓包获得
array[func(member_id)] --> 版本更新后需计算
结合之前对api_port中数组的分析,可以得出结论:
一般情况下每次更新后只需使用member_id尾数分别为0-9的10个账号进行反向计算就可获得新的完整api_port数组。
而即便array[5]与array[17]发生了变化,在同一个账号下获取三个api_port也同样可以反向计算出新的array[5]与array[17],进而计算出整个数组。
array[5]与array[17]没有变化时计算方法如下:
array[func(member_id)] = long.Parse(api_port.Substring(4, 14)) / ((firstFour(member_id) + 1009) * long.Parse(api_port.Substring(22, 5)) - member_id + (firstFour(member_id) + 1000) * array[5] + array[17] - time);