之前写过一个Visual Studio翻译的插件 里面使用了百度,有道,Bing以及Google翻译,其中本想使用google翻译的api来实现,但是Google翻译是要收费的,所以只好直接抓包https://translate.google.com页面中的翻译接口,但是其中有一个比较麻烦的
tk
参数,插件下载地址 : https://marketplace.visualstudio.com/items?itemName=vs-publisher-1462295.VsTranslator 暂只支持Visual Studio 2013 2015
所以找到相关教程以分享
翻译 url :
http://translate.google.cn/translate_a/single?client=t&sl=zh-CN&tl=en&hl=zh-CN&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&source=btn&ssel=0&tsel=0&kc=0&tk=911980.765353&q=%E4%BD%A0%E5%A5%BD
tk
加密过的 且不能随意修改,一个tk
是通过翻译的文本加密而来, 下面是加密js
var TKK = ((function() { var a = 561666268; var b = 1526272306; return 406398 + '.' + (a + b); })()); function b(a, b) { for (var d = 0; d < b.length - 2; d += 3) { var c = b.charAt(d + 2), c = "a" <= c ? c.charCodeAt(0) - 87 : Number(c), c = "+" == b.charAt(d + 1) ? a >>> c : a << c; a = "+" == b.charAt(d) ? a + c & 4294967295 : a ^ c } return a } function tk(a) { for (var e = TKK.split("."), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) { var c = a.charCodeAt(f); 128 > c ? g[d++] = c : (2048 > c ? g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ? (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240, g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128) } a = h; for (d = 0; d < g.length; d++) a += g[d], a = b(a, "+-a^+6"); a = b(a, "+-3^+b+-f"); a ^= Number(e[1]) || 0; 0 > a && (a = (a & 2147483647) + 2147483648); a %= 1E6; return a.toString() + "." + (a ^ h) }
或者下面未加密的js代码
function shiftLeftOrRightThenSumOrXor(num, opArray) { return opArray.reduce((acc, opString) => { var op1 = opString[1]; // '+' | '-' ~ SUM | XOR var op2 = opString[0]; // '+' | '^' ~ SLL | SRL var xd = opString[2]; // [0-9a-f] var shiftAmount = hexCharAsNumber(xd); var mask = (op1 == '+') ? acc >>> shiftAmount : acc << shiftAmount; return (op2 == '+') ? (acc + mask & 0xffffffff) : (acc ^ mask); }, num); } function hexCharAsNumber(xd) { return (xd >= 'a') ? xd.charCodeAt(0) - 87 : Number(xd); } function transformQuery(query) { for (var e = [], f = 0, g = 0; g < query.length; g++) { var l = query.charCodeAt(g); if (l < 128) { e[f++] = l; // 0{l[6-0]} } else if (l < 2048) { e[f++] = l >> 6 | 0xC0; // 110{l[10-6]} e[f++] = l & 0x3F | 0x80; // 10{l[5-0]} } else if (0xD800 == (l & 0xFC00) && g + 1 < query.length && 0xDC00 == (query.charCodeAt(g + 1) & 0xFC00)) { // that's pretty rare... (avoid ovf?) l = (1 << 16) + ((l & 0x03FF) << 10) + (query.charCodeAt(++g) & 0x03FF); e[f++] = l >> 18 | 0xF0; // 111100{l[9-8*]} e[f++] = l >> 12 & 0x3F | 0x80; // 10{l[7*-2]} e[f++] = l & 0x3F | 0x80; // 10{(l+1)[5-0]} } else { e[f++] = l >> 12 | 0xE0; // 1110{l[15-12]} e[f++] = l >> 6 & 0x3F | 0x80; // 10{l[11-6]} e[f++] = l & 0x3F | 0x80; // 10{l[5-0]} } } return e; } function normalizeHash(encondindRound2) { if (encondindRound2 < 0) { encondindRound2 = (encondindRound2 & 0x7fffffff) + 0x80000000; } return encondindRound2 % 1E6; } function calcHash(query, windowTkk) { // STEP 1: spread the the query char codes on a byte-array, 1-3 bytes per char var bytesArray = transformQuery(query); // STEP 2: starting with TKK index, add the array from last step one-by-one, and do 2 rounds of shift+add/xor var d = windowTkk.split('.'); var tkkIndex = Number(d[0]) || 0; var tkkKey = Number(d[1]) || 0; var encondingRound1 = bytesArray.reduce((acc, current) => { acc += current; return shiftLeftOrRightThenSumOrXor(acc, ['+-a', '^+6']) }, tkkIndex); // STEP 3: apply 3 rounds of shift+add/xor and XOR with they TKK key var encondingRound2 = shiftLeftOrRightThenSumOrXor(encondingRound1, ['+-3', '^+b', '+-f']) ^ tkkKey; // STEP 4: Normalize to 2s complement & format var normalizedResult = normalizeHash(encondingRound2); return normalizedResult.toString() + "." + (normalizedResult ^ tkkIndex) } // usage example: var tk = calcHash('hola', '409837.2120040981'); console.log('tk=' + tk); // OUTPUT: 'tk=70528.480109'
google 上的地址 (2017-03-24) 此时的方法Ip=function(a)
: https://translate.google.cn/translate/releases/twsfe_w_20170320_RC00/r/js/desktop_module_main.js
其他参数详情:
sl
- 源语言 (auto代表自动检测) entl
- 目标语言 zh-CNq
- 要翻译的文本 记得url编码一下 你好ie
- 输入的编码 UTF-8oe
- 输出的编码 UTF-8tk
- 上面js加密的结果 911980.765353dt
- may be included more than once and specifies what to return in the reply.Here are some values for dt. If the value is set, the following data will be returned:t
- translation of source textat
- alternate translationsrm
- transcription / transliteration of source and translated textsbd
- dictionary, in case source text is one word (you get translations with articles, reverse translations, etc.)md
- definitions of source text, if it's one wordss
- synonyms of source text, if it's one wordex
- examplesrw
- See also list.
参考: