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
Closed

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

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

Comments

@soimort
Copy link
Owner

@soimort soimort 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 :(
@immortal777
Copy link

@immortal777 immortal777 commented Dec 17, 2015

I have the same

@alexfalcucci
Copy link

@alexfalcucci alexfalcucci commented Dec 17, 2015

Me too.

@if1live
Copy link

@if1live if1live 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
Copy link
Owner Author

@soimort soimort 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
Copy link

@scturtle scturtle 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
Copy link

@if1live if1live 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
Copy link

@if1live if1live 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
Copy link

@dzg dzg 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
Copy link

@alx741 alx741 commented Dec 17, 2015

Same problem here

@soimort
Copy link
Owner Author

@soimort soimort 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
Copy link

@immortal777 immortal777 commented Dec 18, 2015

the question was sent, siikamiika, network.py

@soimort
Copy link
Owner Author

@soimort soimort 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
Copy link

@m00tpoint m00tpoint commented Dec 18, 2015

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

@soimort
Copy link
Owner Author

@soimort soimort commented Dec 18, 2015

@soimort
Copy link
Owner Author

@soimort soimort 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
Copy link

@robertvargason robertvargason 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
Copy link

@matheuss matheuss 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
Copy link

@weaming weaming 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
Development

Successfully merging a pull request may close this issue.