88from  __future__ import  absolute_import 
99
1010import  codecs 
11+ import  ctypes 
1112import  json 
1213import  re 
14+ import  time 
1315
1416from  textblob .compat  import  PY2 , request , urlencode 
1517from  textblob .exceptions  import  TranslatorError , NotTranslated 
@@ -40,6 +42,7 @@ def translate(self, source, from_lang='auto', to_lang='en', host=None, type_=Non
4042            source  =  source .encode ('utf-8' )
4143        data  =  {"client" : "p" ,
4244                "ie" : "UTF-8" , "oe" : "UTF-8" ,
45+                 "dt" : "at" , "tk" : _calculate_tk (source ),
4346                "sl" : from_lang , "tl" : to_lang , "text" : source }
4447        response  =  self ._request (self .url , host = host , type_ = type_ , data = data )
4548        result  =  json .loads (response )
@@ -58,6 +61,7 @@ def detect(self, source, host=None, type_=None):
5861            raise  TranslatorError ('Must provide a string with at least 3 characters.' )
5962        data  =  {"client" : "p" ,
6063                "ie" : "UTF-8" , "oe" : "UTF-8" ,
64+                 "dt" : "at" , "tk" : _calculate_tk (source ),
6165                "sl" : "auto" , "text" : source }
6266        response  =  self ._request (self .url , host = host , type_ = type_ , data = data )
6367        result , language  =  json .loads (response )
@@ -90,3 +94,33 @@ def _unescape(text):
9094    pattern  =  r'\\{1,2}u[0-9a-fA-F]{4}' 
9195    decode  =  lambda  x : codecs .getdecoder ('unicode_escape' )(x .group ())[0 ]
9296    return  re .sub (pattern , decode , text )
97+ 
98+ 
99+ def  _calculate_tk (a ):
100+     """Reverse engineered cross-site request protection.""" 
101+     # Source: https://github.com/soimort/translate-shell/issues/94#issuecomment-165433715 
102+     b  =  int (time .time () /  3600 )
103+ 
104+     if  PY2 :
105+         d  =  map (ord , a )
106+     else :
107+         d  =  a .encode ('utf-8' )
108+ 
109+     def  RL (a , b ):
110+         for  c  in  range (0 , len (b ) -  2 , 3 ):
111+             d  =  b [c + 2 ]
112+             d  =  ord (d ) -  87  if  d  >=  'a'  else  int (d )
113+             xa  =  ctypes .c_uint32 (a ).value 
114+             d  =  xa  >>  d  if  b [c + 1 ] ==  '+'  else  xa  <<  d 
115+             a  =  a  +  d  &  4294967295  if  b [c ] ==  '+'  else  a  ^  d 
116+         return  ctypes .c_int32 (a ).value 
117+ 
118+     a  =  b 
119+     for  di  in  d :
120+         a  =  RL (a  +  di , "+-a^+6" )
121+     a  =  RL (a , "+-3^+b+-f" )
122+     a  =  a  if  a  >=  0  else  ((a  &  2147483647 ) +  2147483648 )
123+     a  %=  pow (10 , 6 )
124+ 
125+     tk  =  '{:d}.{:d}' .format (a , a  ^  b )
126+     return  tk 
0 commit comments