Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Null response as of today (17 Dec 2015) #94

Closed
soimort opened this issue Dec 17, 2015 · 19 comments · Fixed by #95

Comments

@soimort
Copy link
Owner

commented Dec 17, 2015

$ trans 'Goodbye Google'
[ERROR] Null response.
[ERROR] Oops! Something went wrong and I can't translate it for you :(
$ proxychains -q trans 'Goodbye Google'
[ERROR] Null response.
[ERROR] Oops! Something went wrong and I can't translate it for you :(
@soimort soimort added the !important label Dec 17, 2015
@immortal777

This comment has been minimized.

Copy link

commented Dec 17, 2015

I have the same

@alexfalcucci

This comment has been minimized.

Copy link

commented Dec 17, 2015

Me too.

@if1live

This comment has been minimized.

Copy link

commented Dec 17, 2015

I found reason...maybe...
After 17 Dec 2015, google translate API required tk parameter.
I don't know why they modify API,...but after insert tk paramter, It works.

this is example. if valid tk exists, translate-shell works.

if1live@af4aa76

$ ./translate ko:ja "국가"
국가
(gugga)

国
(Kuni)

국가의 번역
[ 한국어 -> 日本語 ]

국가
    国, の国, 国の, の州, 国家

from https://translate.google.com/translate/releases/twsfe_w_20151214_RC03/r/js/desktop_module_main.js

desktop_module_main.js (formatted in chrome) : 8117

, TL = function(a) {
var b;
if (null  === SL) {
    var c = QL(String.fromCharCode(84));
    b = QL(String.fromCharCode(75));
    c = [c(), c()];
    c[1] = b();
    SL = Number(window[c.join(b())]) || 0
}
b = SL;
var d = QL(String.fromCharCode(116))
  , c = QL(String.fromCharCode(107))
  , d = [d(), d()];
d[1] = c();
for (var c = cb + d.join(k) + 
mf, d = [], e = 0, f = 0; f < a.length; f++) {
    var g = a.charCodeAt(f);
    128 > g ? d[e++] = g : (2048 > g ? d[e++] = g >> 6 | 192 : (55296 == (g & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ? (g = 65536 + ((g & 1023) << 10) + (a.charCodeAt(++f) & 1023),
    d[e++] = g >> 18 | 240,
    d[e++] = g >> 12 & 63 | 128) : d[e++] = g >> 12 | 224,
    d[e++] = g >> 6 & 63 | 128),
    d[e++] = g & 63 | 128)
}
a = b || 0;
for (e = 0; e < d.length; e++)
    a += d[e],
    a = RL(a, Vb);
a = RL(a, Ub);
0 > a && (a = (a & 2147483647) + 2147483648);
a %= 1E6;
return c + (a.toString() + dd + (a ^ b))

this function calcuate tk. input 국가 into TL(), then it returns 88946.491205.
if porting this function, we can calcuate tk and this issue will be fixed.

@soimort

This comment has been minimized.

Copy link
Owner Author

commented Dec 17, 2015

I was looking at the issue for the last 10 hours, let me shortly explain why this cannot be elegantly resolved (if not impossible), before I actually fix anything:

The JavaScript function responsible for generating the &tk= parameter, specifically TL(), makes use of the String.prototype.charCodeAt() etc. method to build the access token from the text to be translated.

In AWK (even gawk), there seems to be no builtin method to get the numeric value of a character. While it is easily doable to implement one for the ASCII set (http://www.gnu.org/software/gawk/manual/html_node/Ordinal-Functions.html), we cannot assume our text to be limited to a 256 char map of ASCII; they are the whole Unicode set! Although GNU Awk does handle Unicode characters nicely, the lack of a Unicode ord :: Char -> Int equivalent in AWK, becomes extremely problematic.

It would be as straightforward to port the above JS code to any modern language (and JS is the best, because you can eval). However, AWK is... just AWK. I wasn't expecting too much from it at all.

@scturtle

This comment has been minimized.

Copy link

commented Dec 17, 2015

An ugly python 2/3 port:

import sys
import time
import ctypes


def RL(a, b):
    for c in range(0, len(b)-2, 3):
        d = b[c+2]
        d = ord(d) - 87 if d >= 'a' else int(d)
        xa = ctypes.c_uint32(a).value
        d = xa >> d if b[c+1] == '+' else xa << d
        a = a + d & 4294967295 if b[c] == '+' else a ^ d
    return ctypes.c_int32(a).value


def calc_tk(a):
    b = int(time.time() / 3600)
    if sys.version_info >= (3,):
        d = a.encode('utf-8')
    else:
        d = map(ord, a)
    a = b
    for di in d:
        a = RL(a + di, "+-a^+6")
    a = RL(a, "+-3^+b+-f")
    a = a if a >= 0 else ((a & 2147483647) + 2147483648)
    a %= pow(10, 6)
    return '%d.%d' % (a, a ^ b)

if __name__ == '__main__':
    text = ' '.join(sys.argv[1:])
    print(calc_tk(text))

EDIT: Thanks for @if1live's advices. I make mine work in python 2.

@if1live

This comment has been minimized.

Copy link

commented Dec 17, 2015

I made a proof of concept.
if1live@7294a4e

tk is calcualated by python 3 script.

example : ./translate en:ko -b "open source is awesome."

  1. ./include/calc_tk.py open source is awesome. => 486545.84266
  2. tk is 486545.84266
  3. attach tk when translate-shell request to google translate server.
  4. ????
  5. PROFIT!

Note: how to calculate tk?

  1. convert text to UTF-8 byte array.
  2. prepare unix timestamp's hour. int(time() / 3600)
  3. calculate...(I don't know what algorithm google use)
  4. complete

Note : Don't use python when external script is needed to calcuate tk. Many shift operator is needed to calculate tk. C-like overflow handling is required to calculate tk. With python, it is hard to handle overflow with shift operator. I recommend javascript. (javascript is already implemented by google)

k-001

@if1live

This comment has been minimized.

Copy link

commented Dec 17, 2015

Note

  • I think that SL is unix timestamp's hour. int(time() / 3600)
  • I think that d array is UTF-8 byte array.
@dzg

This comment has been minimized.

Copy link

commented Dec 17, 2015

I love this app! No idea what is being said above, but I'm having the same issue.
Is this fixable by a moron like me?
Thanks @soimort for this lifesaver!

siikamiika added a commit to siikamiika/gt that referenced this issue Dec 17, 2015
@alx741

This comment has been minimized.

Copy link

commented Dec 17, 2015

Same problem here

soimort added a commit that referenced this issue Dec 18, 2015
@soimort

This comment has been minimized.

Copy link
Owner Author

commented Dec 18, 2015

this script not using proxy?

@immortal777 Please elaborate your question a little bit, since I'm not sure what you mean here.

Who are you asking? Which "script" are you referring to, in the scope of this discussion? (is it the JavaScript one, Python one, or the original AWK one?) Moreover, a script cannot be using a proxy on itself, it's you (the user) who chooses a proxy.

@immortal777

This comment has been minimized.

Copy link

commented Dec 18, 2015

the question was sent, siikamiika, network.py

@soimort

This comment has been minimized.

Copy link
Owner Author

commented Dec 18, 2015

@immortal777 then you might want to direct your question to the right place - the maintainers of another project cannot get notified by the comments in this thread automatically (unless they have subscribed to this repo, or you explicitly mentioned them this way @siikamiika).

@m00tpoint

This comment has been minimized.

Copy link

commented Dec 18, 2015

Many many thanks to those who so quickly resolved this problem!

@soimort

This comment has been minimized.

Copy link
Owner Author

commented Dec 18, 2015

soimort added a commit that referenced this issue Dec 18, 2015
@soimort

This comment has been minimized.

Copy link
Owner Author

commented Dec 20, 2015

@oakkitten 👍 seems to work.
Presumably it won't be long before Google starts to validate API token for this, I guess though.

@robertvargason

This comment has been minimized.

Copy link

commented Jan 7, 2016

found the discussion here very helpful for getting my own project working with google translate again. thank you guys!
if anybody needs a sloppy ruby conversion of the above python code:

#!/usr/bin/env ruby

def RL(a, b)
  for c in (0...b.length()-2).step(3)
    d = b[c+2].to_i(16)
    d = (b[c+1] == '+')?(a >> d):(a << d)
    a = (b[c] == '+')?((a + d) & (2**32 - 1)):(a ^ d)
  end
  return a
end

def calc_tk(d)
  time = Time.now().to_i / 3600
  a = time
  d.each_byte do |c|
    a = RL(a + c.ord(), "+-a^+6")
  end
  a = RL(a, "+-3^+b+-f")
  a = ((a & (2**31 - 1)) + (2**31)) if a < 0
  a %= 10**6
  return "#{a}.#{a^time}"
end

puts(calc_tk(ARGV.join(' ')))
@matheuss

This comment has been minimized.

Copy link

commented Jul 1, 2016

Hi there :) Thanks to this (and others) discussions, I came up with a JavaScript module that generates the tk based on a given text 😊 https://github.com/matheuss/google-translate-token

@weaming

This comment has been minimized.

Copy link

commented Apr 10, 2017

Above python version code faild to validate. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.