当前位置: 首页 > news >正文

有道翻译js分析

1 请求分析

截至2025年5月26日,有道翻译的翻译逻辑如下

在这里插入图片描述

2 关键请求参数

输入要翻译的的单词,先发送一个get请求获取认证的key,这里返回的key都是固定的,不排除后期改变或变成动态的

在这里插入图片描述

这个请求包含2个关键参数:mysticTime:13位的时间戳,sign:client=fanyideskweb&mysticTime={13位时间戳}&product=webfanyi&key=asdjnjfenknafdfsdfsd的标准hash值

在这里插入图片描述

返回的翻译结果是加密的,解密在本地完成

在这里插入图片描述

3 sign的生成和解密

这个sign值通过源码全局搜索sign:S可以找到

在这里插入图片描述

返回结果如下,很明显后面可能用到AES128模式加密

{"data": {"secretKey": "Vy4EQ1uwPkUoqvcP1nIu6WiAjxFeA3Y3","aesKey": "ydsecret://query/key/B*RGygVywfNBwpmBaZg*WT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl","aesIv": "ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4"},"code": 0,"msg": "OK"
}

第二次请求是把单词发送过去,拿到翻译结果

这个sign的值和之前有所不同,key不再是asdjnjfenknafdfsdfsd,而是上一个请求返回的secretKey值Vy4EQ1uwPkUoqvcP1nIu6WiAjxFeA3Y3

对应的sign值就是client=fanyideskweb&mysticTime={13位时间戳}&product=webfanyi&key=Vy4EQ1uwPkUoqvcP1nIu6WiAjxFeA3Y3的标准MD5

在这里插入图片描述

解密的话,就一笔带过了

import base64
from Crypto.Cipher import AES
from get_secret_key import get_fanyi_data
import hashlib
from Crypto.Util.Padding import unpad# 目前key和iv是固定的,可以写死
origin_key = "ydsecret://query/key/B*RGygVywfNBwpmBaZg*WT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl"
origin_iv = "ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4"
key = get_md5(origin_key)
iv = get_md5(origin_iv)aes = AES.new(mode=AES.MODE_CBC, key=key, iv=iv)
data = aes.decrypt("要解密的密文")data = unpad(data, 16)
print("解密后的数据:")
print(data.decode())

4 完整代码示例

decrypt.py          # 输入要翻译的内容,解密返回的密文
get_secret_key.py   # 在一次请求时获取key
get_sign.py         # 生成2次不同的sign值,和时间戳

decrypt.py

import base64
from Crypto.Cipher import AES
from get_secret_key import get_fanyi_data
import hashlib
from Crypto.Util.Padding import unpad# 返回值
def base64_decode(str_b64):str1 = get_fanyi_data(str_b64)str_base64 = str1.replace("-", "+").replace("_", "/")encrypt_data = base64.b64decode(str_base64)return encrypt_datadef get_md5(data):m = hashlib.md5()m.update(data.encode())return m.digest()def fanyi(question):origin_key = "ydsecret://query/key/B*RGygVywfNBwpmBaZg*WT7SIOUP2T0C9WHMZN39j^DAdaZhAnxvGcCY6VYFwnHl"origin_iv = "ydsecret://query/iv/C@lZe2YzHtZ2CYgaXKSVfsb7Y4QWHjITPPZ0nQp87fBeJ!Iv6v^6fvi2WN@bYpJ4"key = get_md5(origin_key)iv = get_md5(origin_iv)aes = AES.new(mode=AES.MODE_CBC, key=key, iv=iv)data = aes.decrypt(base64_decode(question))data = unpad(data, 16)print("解密后的数据:")print(data.decode())fanyi("python is js")

get_secret_key.py

from time import time
import requests
from get_sign import get_fanyi_signdef get_fanyi_data(question):headers = {"Accept": "application/json, text/plain, */*","Accept-Language": "zh-CN,zh;q=0.9","Connection": "keep-alive","Content-Type": "application/x-www-form-urlencoded","Origin": "https://fanyi.youdao.com","Referer": "https://fanyi.youdao.com/","Sec-Fetch-Dest": "empty","Sec-Fetch-Mode": "cors","Sec-Fetch-Site": "same-site","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/527.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/517.36","sec-ch-ua": "\"Not_A Brand\";v=\"99\", \"Google Chrome\";v=\"109\", \"Chromium\";v=\"109\"","sec-ch-ua-mobile": "?0","sec-ch-ua-platform": "\"Windows\""}cookies = {#"OUTFOX_SEARCH_USER_ID": "3XXXX0","OUTFOX_SEARCH_USER_ID_NCOO": str(time()),"DICT_DOCTRANS_SESSION_ID": "MjU0OGJlYTYtNmEyNi00NTQ3LWJlNDAtZWQ2YjJlZDJmYzdl","_uetsid": "9168cc2038b911f09d2c617b3a1918df","_uetvid": "9168ded038b911f0945f619932fea989"}url = "https://dict.youdao.com/webtranslate"sign, mysticTime, secret = get_fanyi_sign()data = {"i": question,"from": "en","to": "zh-CHS","useTerm": "false","domain": "0","dictResult": "true","keyid": "webfanyi","sign": sign,"client": "fanyideskweb","product": "webfanyi","appVersion": "1.0.0","vendor": "web","pointParam": "client,mysticTime,product","mysticTime": mysticTime,"keyfrom": "fanyi.web","mid": "1","screen": "1","model": "1","network": "wifi","abtest": "0","yduuid": "abcdefg"}response = requests.post(url=url, cookies=cookies, headers=headers, data=data)response.encoding = response.apparent_encodingreturn response.text

get_sign.py

from hashlib import md5
from time import time
import json
import requestsdef get_common_sign():md5_obj = md5()timestamp = str(int((time() * 1000)))input_str = f"client=fanyideskweb&mysticTime={timestamp}&product=webfanyi&key=asdjnjfenknafdfsdfsd".encode("utf-8")md5_obj.update(input_str)md5_str = md5_obj.hexdigest()# print(md5_str, timestamp)return md5_str, timestampdef get_secret():url = "https://dict.youdao.com/webtranslate/key"cookies = {# 'OUTFOX_SEARCH_USER_ID': '31xx5363@xxxxxx0','OUTFOX_SEARCH_USER_ID_NCOO': str(time()),'_uetsid': '9168cc2038b911f09d2c617b3a1918df','_uetvid': '9168ded038b911f0945f619932fea989','DICT_DOCTRANS_SESSION_ID': 'OTgwZWEyZjEtYjBjNi00MTRjLWE3NGUtMjEzZjg5OGM1NTY2',}headers = {'Accept': 'application/json, text/plain, */*','Accept-Language': 'zh-CN,zh;q=0.9','Connection': 'keep-alive','Origin': 'https://fanyi.youdao.com','Referer': 'https://fanyi.youdao.com/','Sec-Fetch-Dest': 'empty','Sec-Fetch-Mode': 'cors','Sec-Fetch-Site': 'same-site','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/577.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/237.36','sec-ch-ua': '"Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"','sec-ch-ua-mobile': '?0','sec-ch-ua-platform': '"Windows"',}sign, mysticTime = get_common_sign()params = (('keyid', 'webfanyi-key-getter'),('sign', sign),('client', 'fanyideskweb'),('product', 'webfanyi'),('appVersion', '1.0.0'),('vendor', 'web'),('pointParam', 'client,mysticTime,product'),('mysticTime', mysticTime),('keyfrom', 'fanyi.web'),('mid', '1'),('screen', '1'),('model', '1'),('network', 'wifi'),('abtest', '0'),('yduuid', 'abcdefg'),)response = requests.get(url=url, headers=headers, params=params, cookies=cookies)response.encoding = response.apparent_encodingsecret = response.json()return secretdef get_fanyi_sign():md5_obj = md5()timestamp = str(int((time() * 1000)))secret = get_secret()key = secret.get("data").get("secretKey")# print(key)input_str = f"client=fanyideskweb&mysticTime={timestamp}&product=webfanyi&key={key}".encode("utf-8")md5_obj.update(input_str)md5_str = md5_obj.hexdigest()return md5_str, timestamp, secret

相关文章:

  • 《函数栈帧的创建和销毁》
  • 【Fifty Project - D32】
  • HTML5基础
  • github actions入门指南
  • C++030(内联函数)
  • Vision Pro发布!开发者如何快速上手空间UI设计?
  • 深入理解计算机科学中的“递归”:原理、应用与优化
  • 我的世界模组开发——方块的深入探索(1)
  • 【深度学习-pytorch篇】5. 卷积神经网络与LLaMA分类模型
  • qemu安装risc-V 64
  • WPF的基础设施:XAML基础语法
  • 利用仿真软件学习一下RC无源滤波和有源滤波电路
  • 第二节 LED模块
  • 电脑革命家测试版:硬件检测,6MB 轻量无广告 清理垃圾 + 禁用系统更新
  • Nacos注册中心原理
  • 算法-背包问题
  • 交换机环路故障分析以及解决方案
  • CAD背景怎么改成黑色?
  • web第七次课后作业--springbootWeb响应
  • 大型软件系统日志记录最佳实践
  • 重庆模板网站建设怎么样/软件开发app制作公司
  • 做地方网站要办什么证/电商网站分析
  • 深圳团购网站设计哪家好/微信如何投放广告
  • 金蝶软件怎么打印凭证/长尾词seo排名
  • 武汉建筑公司网站/实时疫情最新消息数据
  • 网站建设的作用有哪些方面/百度网首页