文档翻译 API 简介
说明
Hi,您好,欢迎使用有道智云文档翻译API接口服务。
本文档主要针对需要集成HTTP API的技术开发工程师,详细描述文档翻译能力相关的技术内容。
如果您有与我们商务合作的需求,可以通过以下方式联系我们:
商务邮箱:
[email protected]
如果您对文档内容有任何疑问,可以通过以下几种方式联系我们:
客服QQ:1906538062
智云翻译技术交流QQ 1群: 652880659
智云翻译技术交流QQ 2群: 669384425
智云翻译技术交流QQ 3群: 807539209
智云翻译技术交流QQ 4群: 936752411
联系邮箱:
[email protected]
温馨提示:
-
本文档主要针对开发人员,接入测试前需要获取应用ID和应用密钥;如果您还没有,请按照
新手指南
获取。
-
平台向每个账户赠送50元的体验金,供用户集成前测试所用,具体资费规则详见
文档翻译服务报价
。
接口说明
文档翻译API接口提供有道的文档翻译服务。您只需要通过调用文档翻译API,传入文档的Base64编码,指定源语言与目标语言,通过POST请求方式,就可以将文档中的文字内容进行翻译。
文档翻译 API HTTPS地址:
https://openapi.youdao.com/file_trans/upload
https://openapi.youdao.com/file_trans/query
https://openapi.youdao.com/file_trans/download
协议须知
调用方在集成文本翻译API时,请遵循以下规则。
规则
|
描述
|
传输方式
|
HTTPS
|
请求方式
|
POST
|
字符编码
|
统一使用UTF-8 编码
|
请求格式
|
表单
|
响应格式
|
JSON
|
接口调用参数
调用API需要向接口发送以下字段来访问服务。
字段名
|
类型
|
含义
|
必填
|
备注
|
q
|
text
|
待翻译文档
|
True
|
文档的Base64编码,大小限制为40M(编码后)
|
fileName
|
text
|
文档名称
|
True
|
fileType
|
text
|
文档类型
|
True
|
docx/pdf/doc/jpg/png/bmp/ppt/pptx/xlsx
|
langFrom
|
text
|
源语言
|
True
|
en/zh-CHS
|
langTo
|
text
|
目标语言
|
True
|
en/zh-CHS
|
appKey
|
text
|
应用ID
|
True
|
可在
应用管理
查看
|
salt
|
text
|
UUID
|
True
|
uuid,唯一通用识别码
|
curtime
|
text
|
当前UTC时间戳(秒)
|
True
|
时间戳timestamp
|
sign
|
text
|
签名
|
True
|
sha256(应用ID+input+salt+curtime+应用密钥)
|
docType
|
text
|
服务器响应类型
|
True
|
json
|
signType
|
text
|
签名类型
|
True
|
v3
|
字段名
|
类型
|
含义
|
必填
|
备注
|
flownumber
|
text
|
文档流水号
|
True
|
从文档上传接口获取
|
appKey
|
text
|
应用ID
|
True
|
可在
应用管理
查看
|
salt
|
text
|
UUID
|
True
|
curtime
|
text
|
当前UTC时间戳(秒)
|
True
|
sign
|
text
|
签名
|
True
|
sha256(应用ID+input+salt+curtime+应用密钥)
|
docType
|
text
|
服务器响应类型
|
True
|
json
|
signType
|
text
|
签名类型
|
True
|
v3
|
字段名
|
类型
|
含义
|
必填
|
备注
|
flownumber
|
text
|
文档流水号
|
True
|
从文档上传接口获取
|
downloadFileType
|
text
|
下载类型
|
True
|
word/ppt/xlsx
|
appKey
|
text
|
应用ID
|
True
|
可在
应用管理
查看
|
salt
|
text
|
UUID
|
True
|
curtime
|
text
|
当前UTC时间戳(秒)
|
True
|
sign
|
text
|
签名
|
True
|
sha256(应用ID+input+salt+curtime+应用密钥)
|
docType
|
text
|
服务器响应类型
|
True
|
json
|
signType
|
text
|
签名类型
|
True
|
v3
|
签名生成方法如下:
sha256(
应用ID
+
input
+
salt
+
curtime
+
应用密钥
)
其中,input的计算方式为:
input
=
Base64(q)字符串
(当Base64(q)长度小于等于20)
或
input
=
Base64(q)前10个字符前10个字符
+
Base64(q)长度
+
Base64(q)后十个字符
(当Base64(q)长度大于20)
input
=
flownumber字符串
(当flownumber长度小于等于20)。
或
input
=
flownumber前10个字符前10个字符
+
flownumber长度
+
flownumber后十个字符
(当flownumber长度大于20)
不同语言获取时间戳,请参看
此链接
如果对签名有疑问,可以参看文档末尾各语言demo。
输出结果
返回的结果是json格式,具体说明如下:
字段名
|
类型
|
字段说明
|
errorCode
|
text
|
错误码,一定存在
|
flownumber
|
text
|
文档流水号,上传成功一定存在
|
字段名
|
类型
|
字段说明
|
errorCode
|
text
|
错误码,一定存在
|
status
|
text
|
进度状态码,查询成功一定存在
|
statusString
|
text
|
进度状态描述,查询成功一定存在
|
-
文档下载接口
若
Content-Type
为
application/json
,表示下载失败,返回值为json,否则返回值为文件流。
字段名
|
类型
|
字段说明
|
errorCode
|
text
|
错误码,下载失败时存在
|
示例
返回结果:
{
"errorCode": "0", //错误码
"flownumber": "C9193F8204484E51B7DDA604137AEE3D" //文档流水号
返回结果:
{
"errorCode": "0", //错误码
"status": 1, //状态码
"statusString": "上传中' //状态描述
失败时返回结果:
{
"errorCode": "0" //错误码
支持的语言表
下表为各语言对应代码:
文档状态码
状态码
|
含义
|
1
|
上传中
|
2
|
转换中
|
3
|
翻译中
|
4
|
已完成
|
5
|
生成中
|
-1
|
上传失败
|
-2
|
转换失败
|
-3
|
翻译失败
|
-4
|
已取消
|
-5
|
生成失败
|
-10
|
翻译失败
|
-11
|
文件被删除
|
服务配置
上传格式
|
下载格式
|
单文档大小(M)
|
支持语言
|
Word/PDF
|
Word
|
40M内(编码后)
|
中英互译
|
错误代码列表
错误码
|
含义
|
101
|
缺少必填的参数,首先确保必填参数齐全,然后,确认参数书写是否正确。
|
102
|
不支持的语言类型
|
103
|
翻译文本过长
|
104
|
不支持的API类型
|
105
|
不支持的签名类型
|
106
|
不支持的响应类型
|
107
|
不支持的传输加密类型
|
108
|
应用ID无效,注册账号,登录后台创建应用和实例并完成绑定,可获得应用ID和应用密钥等信息
|
109
|
batchLog格式不正确
|
110
|
无相关服务的有效实例,应用没有绑定服务实例,可以新建服务实例,绑定服务实例。注:某些服务的翻译结果发音需要tts实例,需要在控制台创建语音合成实例绑定应用后方能使用。
|
111
|
开发者账号无效
|
112
|
请求服务无效
|
113
|
q不能为空
|
114
|
不支持的图片传输方式
|
201
|
解密失败,可能为DES,BASE64,URLDecode的错误
|
202
|
签名检验失败,如果确认应用ID和应用密钥的正确性,仍返回202,一般是编码问题。请确保翻译文本
q
为UTF-8编码.
|
203
|
访问IP地址不在可访问IP列表
|
205
|
请求的接口与应用的平台类型不一致,确保接入方式(Android SDK、IOS SDK、API)与创建的应用平台类型一致。如有疑问请参考
入门指南
[]()
|
206
|
因为时间戳无效导致签名校验失败
|
207
|
重放请求
|
301
|
辞典查询失败
|
302
|
翻译查询失败
|
303
|
服务端的其它异常
|
304
|
会话闲置太久超时
|
401
|
账户已经欠费停
|
402
|
offlinesdk不可用
|
411
|
访问频率受限,请稍后访问
|
412
|
长请求过于频繁,请稍后访问
|
1001
|
无效的OCR类型
|
1002
|
不支持的OCR image类型
|
1003
|
不支持的OCR Language类型
|
1004
|
识别图片过大
|
1201
|
图片base64解密失败
|
1301
|
OCR段落识别失败
|
1411
|
访问频率受限
|
1412
|
超过最大识别字节数
|
2003
|
不支持的语言识别Language类型
|
2004
|
合成字符过长
|
2005
|
不支持的音频文件类型
|
2006
|
不支持的发音类型
|
2201
|
解密失败
|
2301
|
服务的异常
|
2411
|
访问频率受限,请稍后访问
|
2412
|
超过最大请求字符数
|
3001
|
不支持的语音格式
|
3002
|
不支持的语音采样率
|
3003
|
不支持的语音声道
|
3004
|
不支持的语音上传类型
|
3005
|
不支持的语言类型
|
3006
|
不支持的识别类型
|
3007
|
识别音频文件过大
|
3008
|
识别音频时长过长
|
3009
|
不支持的音频文件类型
|
3010
|
不支持的发音类型
|
3201
|
解密失败
|
3301
|
语音识别失败
|
3302
|
语音翻译失败
|
3303
|
服务的异常
|
3411
|
访问频率受限,请稍后访问
|
3412
|
超过最大请求字符数
|
4001
|
不支持的语音识别格式
|
4002
|
不支持的语音识别采样率
|
4003
|
不支持的语音识别声道
|
4004
|
不支持的语音上传类型
|
4005
|
不支持的语言类型
|
4006
|
识别音频文件过大
|
4007
|
识别音频时长过长
|
4201
|
解密失败
|
4301
|
语音识别失败
|
4303
|
服务的异常
|
4411
|
访问频率受限,请稍后访问
|
4412
|
超过最大请求时长
|
5001
|
无效的OCR类型
|
5002
|
不支持的OCR image类型
|
5003
|
不支持的语言类型
|
5004
|
识别图片过大
|
5005
|
不支持的图片类型
|
5006
|
文件为空
|
5201
|
解密错误,图片base64解密失败
|
5301
|
OCR段落识别失败
|
5411
|
访问频率受限
|
5412
|
超过最大识别流量
|
9001
|
不支持的语音格式
|
9002
|
不支持的语音采样率
|
9003
|
不支持的语音声道
|
9004
|
不支持的语音上传类型
|
9005
|
不支持的语音识别 Language类型
|
9301
|
ASR识别失败
|
9303
|
服务器内部错误
|
9411
|
访问频率受限(超过最大调用次数)
|
9412
|
超过最大处理语音长度
|
10001
|
无效的OCR类型
|
10002
|
不支持的OCR image类型
|
10004
|
识别图片过大
|
10201
|
图片base64解密失败
|
10301
|
OCR段落识别失败
|
10411
|
访问频率受限
|
10412
|
超过最大识别流量
|
11001
|
不支持的语音识别格式
|
11002
|
不支持的语音识别采样率
|
11003
|
不支持的语音识别声道
|
11004
|
不支持的语音上传类型
|
11005
|
不支持的语言类型
|
11006
|
识别音频文件过大
|
11007
|
识别音频时长过长,最大支持30s
|
11201
|
解密失败
|
11301
|
语音识别失败
|
11303
|
服务的异常
|
11411
|
访问频率受限,请稍后访问
|
11412
|
超过最大请求时长
|
12001
|
图片尺寸过大
|
12002
|
图片base64解密失败
|
12003
|
引擎服务器返回错误
|
12004
|
图片为空
|
12005
|
不支持的识别图片类型
|
12006
|
图片无匹配结果
|
13001
|
不支持的角度类型
|
13002
|
不支持的文件类型
|
13003
|
表格识别图片过大
|
13004
|
文件为空
|
13301
|
表格识别失败
|
15001
|
需要图片
|
15002
|
图片过大(1M)
|
15003
|
服务调用失败
|
17001
|
需要图片
|
17002
|
图片过大(1M)
|
17003
|
识别类型未找到
|
17004
|
不支持的识别类型
|
17005
|
服务调用失败
|
18001
|
需要参数
|
18002
|
需要流水号
|
18003
|
需要文件名
|
18004
|
需要文件类型
|
18005
|
需要源语言
|
18006
|
需要目标语言
|
18007
|
需要翻译文件
|
18008
|
上传文件失败
|
18009
|
错误的流水号
|
18010
|
未完成
|
18011
|
转换失败
|
18012
|
找不到文件
|
18013
|
需要文件下载类型
|
18014
|
不支持的语言
|
18015
|
不支持的文件类型
|
18016
|
不支持的下载类型
|
18017
|
文件过大
|
常用语言 Demo
Java 示例
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
public class Demo {
private static Logger logger = LoggerFactory.getLogger(Demo.class);
private static final String YOUDAO_URL_UPLOAD = "https://openapi.youdao.com/file_trans/upload";
private static final String YOUDAO_URL_QUERY = "https://openapi.youdao.com/file_trans/query";
private static final String YOUDAO_URL_DOWNLOAD = "https://openapi.youdao.com/file_trans/download";
private static final String APP_KEY = "您的应用ID";
private static final String APP_SECRET = "您的应用密钥";
public static void main(String[] args) throws IOException {
upload();
query();
download();
public static void upload() throws IOException {
Map<String,String> params = new HashMap<String,String>();
String q = loadAsBase64("文件的路径");
String salt = String.valueOf(System.currentTimeMillis());
String curtime = String.valueOf(System.currentTimeMillis() / 1000);
String signStr = APP_KEY + truncate(q) + salt + curtime + APP_SECRET;
String sign = getDigest(signStr);
params.put("q", q);
params.put("fileName", "文件名称");
params.put("fileType", "文件类型");
params.put("langFrom", "源语言");
params.put("langTo", "目标语言");
params.put("appKey", APP_KEY);
params.put("salt", salt);
params.put("curtime", curtime);
params.put("sign", sign);
params.put("docType", "json");
params.put("signType", "v3");
String result = requestForHttp(YOUDAO_URL_UPLOAD, params);
/** 处理结果 */
System.out.println(result);
public static void query() throws IOException {
Map<String,String> params = new HashMap<String,String>();
String flownumber = "文件流水号";
String salt = String.valueOf(System.currentTimeMillis());
String curtime = String.valueOf(System.currentTimeMillis() / 1000);
String signStr = APP_KEY + truncate(flownumber) + salt + curtime + APP_SECRET;
String sign = getDigest(signStr);
params.put("flownumber", flownumber);
params.put("appKey", APP_KEY);
params.put("salt", salt);
params.put("curtime", curtime);
params.put("sign", sign);
params.put("docType", "json");
params.put("signType", "v3");
String result = requestForHttp(YOUDAO_URL_QUERY, params);
/** 处理结果 */
System.out.println(result);
public static void download() throws IOException {
Map<String,String> params = new HashMap<String,String>();
String flownumber = "文件流水号";
String salt = String.valueOf(System.currentTimeMillis());
String curtime = String.valueOf(System.currentTimeMillis() / 1000);
String signStr = APP_KEY + truncate(flownumber) + salt + curtime + APP_SECRET;
String sign = getDigest(signStr);
params.put("flownumber", flownumber);
params.put("downloadFileType", "文件下载类型");
params.put("appKey", APP_KEY);
params.put("salt", salt);
params.put("curtime", curtime);
params.put("sign", sign);
params.put("docType", "json");
params.put("signType", "v3");
String result = requestForHttp(YOUDAO_URL_DOWNLOAD, params);
/** 处理结果 */
System.out.println(result);
public static String requestForHttp(String url,Map<String,String> params) throws IOException {
String result = "";
/** 创建HttpClient */
CloseableHttpClient httpClient = HttpClients.createDefault();
/** httpPost */
HttpPost httpPost = new HttpPost(url);
List<NameValuePair> paramsList = new ArrayList<NameValuePair>();
Iterator<Map.Entry<String,String>> it = params.entrySet().iterator();
while(it.hasNext()){
Map.Entry<String,String> en = it.next();
String key = en.getKey();
String value = en.getValue();
paramsList.add(new BasicNameValuePair(key,value));
httpPost.setEntity(new UrlEncodedFormEntity(paramsList,"UTF-8"));
CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
result = EntityUtils.toString(httpEntity,"UTF-8");
EntityUtils.consume(httpEntity);
}finally {
if(httpResponse!=null){
httpResponse.close();
}catch(IOException e){
logger.info("## release resouce error ##" + e);
return result;
* 生成加密字段
public static String getDigest(String string) {
if (string == null) {
return null;
char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
byte[] btInput = string.getBytes(StandardCharsets.UTF_8);
try {
MessageDigest mdInst = MessageDigest.getInstance("SHA-256");
mdInst.update(btInput);
byte[] md = mdInst.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (byte byte0 : md) {
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
return new String(str);
} catch (NoSuchAlgorithmException e) {
return null;
public static String loadAsBase64(String imgFile)
{//将文件转化为字节数组字符串,并对其进行Base64编码处理
File file = new File(imgFile);
if(!file.exists()){
logger.error("文件不存在");
return null;
InputStream in = null;
byte[] data = null;
//读取文件字节数组
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
in.close();
catch (IOException e)
e.printStackTrace();
//对字节数组Base64编码
return Base64.getEncoder().encodeToString(data);//返回Base64编码过的字节数组字符串
public static String truncate(String q) {
if (q == null) {
return null;
int len = q.length();
String result;
return len <= 20 ? q : (q.substring(0, 10) + len + q.substring(len - 10, len));
}
Python 示例
# -*- coding: utf-8 -*-
import sys
import uuid
import requests
import base64
import hashlib
import time
reload(sys)
sys.setdefaultencoding('utf-8')
YOUDAO_URL_UPLOAD = 'https://openapi.youdao.com/file_trans/upload'
YOUDAO_URL_QUERY = 'https://openapi.youdao.com/file_trans/query'
YOUDAO_URL_DOWNLOAD = 'https://openapi.youdao.com/file_trans/download'
APP_KEY = '您的应用ID'
APP_SECRET = '您的应用密钥'
def truncate(q):
if q is None:
return None
q_utf8 = q.decode("utf-8")
size = len(q_utf8)
return q_utf8 if size <= 20 else q_utf8[0:10] + str(size) + q_utf8[size - 10:size]
def encrypt(signStr):
hash_algorithm = hashlib.sha256()
hash_algorithm.update(signStr.encode('utf-8'))
return hash_algorithm.hexdigest()
def do_request(url, data):
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
return requests.post(url, data=data, headers=headers)
def upload():
f = open(r'文件的路径', 'rb') # 二进制方式打开文件
q = base64.b64encode(f.read()) # 读取文件内容,转换为base64编码
f.close()
salt = str(uuid.uuid1())
curtime = str(int(time.time()))
signStr = APP_KEY + truncate(q) + salt + curtime + APP_SECRET
sign = encrypt(signStr)
data = {}
data['q'] = q
data['fileName'] = '文件名称'
data['fileType'] = '文件类型'
data['langFrom'] = '源语言'
data['langTo'] = '目标语言'
data['appKey'] = APP_KEY
data['salt'] = salt
data['curtime'] = curtime
data['sign'] = sign
data['docType'] = 'json'
data['signType'] = 'v3'
response = do_request(YOUDAO_URL_UPLOAD, data)
print response.content
def query():
flownumber = '文件流水号'
salt = str(uuid.uuid1())
curtime = str(int(time.time()))
signStr = APP_KEY + truncate(flownumber) + salt + curtime + APP_SECRET
sign = encrypt(signStr)
data = {}
data['flownumber'] = flownumber
data['appKey'] = APP_KEY
data['salt'] = salt
data['curtime'] = curtime
data['sign'] = sign
data['docType'] = 'json'
data['signType'] = 'v3'
response = do_request(YOUDAO_URL_QUERY, data)
print response.content
def download():
flownumber = '文件流水号'
salt = str(uuid.uuid1())
curtime = str(int(time.time()))
signStr = APP_KEY + truncate(flownumber) + salt + curtime + APP_SECRET
sign = encrypt(signStr)
data = {}
data['flownumber'] = flownumber
data['downloadFileType'] = '文件下载类型'
data['appKey'] = APP_KEY
data['salt'] = salt
data['curtime'] = curtime
data['sign'] = sign
data['docType'] = 'json'
data['signType'] = 'v3'
response = do_request(YOUDAO_URL_DOWNLOAD, data)
print response.content
if __name__ == '__main__':
upload()
query()
download()
C# 示例
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Collections.Generic;
using System.Security.Cryptography;
namespace zhiyun_csharp_demo
class Demo
public static void Main()
Upload();
Query();
Download();
protected static void Upload() {
Dictionary dic = new Dictionary();
string appKey = "您的应用ID";
string appSecret = "您的应用密钥";
string url = "https://openapi.youdao.com/file_trans/upload";
string q = LoadAsBase64("文件的路径");
string salt = DateTime.Now.Millisecond.ToString();
TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
long millis = (long) ts.TotalMilliseconds;
string curtime = Convert.ToString(millis / 1000);
string signStr = appKey + Truncate(q) + salt + curtime + appSecret;;
string sign = ComputeHash(signStr, new SHA256CryptoServiceProvider());
dic.Add("q", System.Web.HttpUtility.UrlEncode(q));
dic.Add("fileName", "文件名称");
dic.Add("fileType", "文件类型");
dic.Add("langFrom", "源语言");
dic.Add("langTo", "目标语言");
dic.Add("appKey", appKey);
dic.Add("salt", salt);
dic.Add("curtime", curtime);
dic.Add("sign", sign);
dic.Add("docType", "json");
dic.Add("signType", "v3");
string result = Post(url, dic);
Console.WriteLine(result);
protected static void Query() {
Dictionary dic = new Dictionary();
string appKey = "您的应用ID";
string appSecret = "您的应用密钥";
string url = "https://openapi.youdao.com/file_trans/query";
string flownumber = "文件流水号";
string salt = DateTime.Now.Millisecond.ToString();
TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
long millis = (long) ts.TotalMilliseconds;
string curtime = Convert.ToString(millis / 1000);
string signStr = appKey + Truncate(flownumber) + salt + curtime + appSecret;;
string sign = ComputeHash(signStr, new SHA256CryptoServiceProvider());
dic.Add("flownumber", flownumber);
dic.Add("appKey", appKey);
dic.Add("salt", salt);
dic.Add("curtime", curtime);
dic.Add("sign", sign);
dic.Add("docType", "json");
dic.Add("signType", "v3");
string result = Post(url, dic);
Console.WriteLine(result);
protected static void Download() {
Dictionary dic = new Dictionary();
string appKey = "您的应用ID";
string appSecret = "您的应用密钥";
string url = "https://openapi.youdao.com/file_trans/download";
string flownumber = "文件流水号";
string salt = DateTime.Now.Millisecond.ToString();
TimeSpan ts = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc));
long millis = (long) ts.TotalMilliseconds;
string curtime = Convert.ToString(millis / 1000);
string signStr = appKey + Truncate(flownumber) + salt + curtime + appSecret;;
string sign = ComputeHash(signStr, new SHA256CryptoServiceProvider());
dic.Add("flownumber", flownumber);
dic.Add("downloadFileType", "文件下载类型");
dic.Add("appKey", appKey);
dic.Add("salt", salt);
dic.Add("curtime", curtime);
dic.Add("sign", sign);
dic.Add("docType", "json");
dic.Add("signType", "v3");
string result = Post(url, dic);
Console.WriteLine(result);
protected static string ComputeHash(string input, HashAlgorithm algorithm)
Byte[] inputBytes = Encoding.UTF8.GetBytes(input);
Byte[] hashedBytes = algorithm.ComputeHash(inputBytes);
return BitConverter.ToString(hashedBytes).Replace("-", "");
protected static string Truncate(string q)
if (q == null)
return null;
int len = q.Length;
return len <= 20 ? q : (q.Substring(0, 10) + len + q.Substring(len - 10, 10));
protected static string LoadAsBase64(string filename)
FileStream filestream = new FileStream(filename, FileMode.Open);
byte[] arr = new byte[filestream.Length];
filestream.Position = 0;
filestream.Read(arr, 0, (int)filestream.Length);
filestream.Close();
return Convert.ToBase64String(arr);
catch (Exception ex)
return null;
protected static string Post(string url, Dictionary dic)
string result = "";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
StringBuilder builder = new StringBuilder();
int i = 0;
foreach (var item in dic)
if (i > 0)
builder.Append("&");
builder.AppendFormat("{0}={1}", item.Key, item.Value);
byte[] data = Encoding.UTF8.GetBytes(builder.ToString());
req.ContentLength = data.Length;
using (Stream reqStream = req.GetRequestStream())
reqStream.Write(data, 0, data.Length);
reqStream.Close();
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
Stream stream = resp.GetResponseStream();
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
result = reader.ReadToEnd();
return result;
}
PHP 示例
<?php
define("CURL_TIMEOUT", 2000);
define("URL_UPLOAD", "https://openapi.youdao.com/file_trans/upload");
define("URL_QUERY", "https://openapi.youdao.com/file_trans/query");
define("URL_DOWNLOAD", "https://openapi.youdao.com/file_trans/download");
define("APP_KEY", "您的应用ID"); // 替换为您的应用ID
define("SEC_KEY", "您的应用密钥"); // 替换为您的密钥
function upload()
$file = "文件的路径";
$fp = fopen($file, "r") or die("Can't open file");
// base64编码
$q = base64_encode(fread($fp, filesize($file)));
fclose($fp);
$salt = create_guid();
$curtime = strtotime("now");
$signStr = APP_KEY . truncate($q) . $salt . $curtime . SEC_KEY;
$args = array(
'appKey' => APP_KEY,
'salt' => $salt,
$args['q'] = $q;
$args['fileName'] = '文件名称';
$args['fileType'] = '文件类型';
$args['langFrom'] = '源语言';
$args['langTo'] = '目标语言';
$args['curtime'] = $curtime;
$args['sign'] = hash("sha256", $signStr);
$args['docType'] = 'json';
$args['signType'] = 'v3';
$ret = call(URL_UPLOAD, $args);
print_r($ret);
$ret = json_decode($ret, true);
return $ret;
function query()
$flownumber = "文件流水号";
$salt = create_guid();
$curtime = strtotime("now");
$signStr = APP_KEY . truncate($flownumber) . $salt . $curtime . SEC_KEY;
$args = array(
'appKey' => APP_KEY,
'salt' => $salt,
$args['flownumber'] = $flownumber;
$args['curtime'] = $curtime;
$args['sign'] = hash("sha256", $signStr);
$args['docType'] = 'json';
$args['signType'] = 'v3';
$ret = call(URL_QUERY, $args);
print_r($ret);
$ret = json_decode($ret, true);
return $ret;
function download()
$flownumber = "文件流水号";
$salt = create_guid();
$curtime = strtotime("now");
$signStr = APP_KEY . truncate($flownumber) . $salt . $curtime . SEC_KEY;
$args = array(
'appKey' => APP_KEY,
'salt' => $salt,
$args['flownumber'] = $flownumber;
$args['downloadFileType'] = '文件下载类型';
$args['curtime'] = $curtime;
$args['sign'] = hash("sha256", $signStr);
$args['docType'] = 'json';
$args['signType'] = 'v3';
$ret = call(URL_DOWNLOAD, $args);
print_r($ret);
$ret = json_decode($ret, true);
return $ret;
// 发起网络请求
function call($url, $args=null, $method="post", $testflag = 0, $timeout = CURL_TIMEOUT, $headers=array())
$ret = false;
$i = 0;
while($ret === false)
if($i > 1)
break;
if($i > 0)
sleep(1);
$ret = callOnce($url, $args, $method, false, $timeout, $headers);
$i++;
return $ret;
function callOnce($url, $args=null, $method="post", $withCookie = false, $timeout = CURL_TIMEOUT, $headers=array())
$ch = curl_init();
if($method == "post")
$data = convert($args);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_POST, 1);
$data = convert($args);
if($data)
if(stripos($url, "?") > 0)
$url .= "&$data";
$url .= "?$data";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if(!empty($headers))
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if($withCookie)
curl_setopt($ch, CURLOPT_COOKIEJAR, $_COOKIE);
$r = curl_exec($ch);
curl_close($ch);
return $r;
function convert(&$args)
$data = '';
if (is_array($args))
foreach ($args as $key=>$val)
if (is_array($val))
foreach ($val as $k=>$v)
$data .= $key.'['.$k.']='.rawurlencode($v).'&';
$data .="$key=".rawurlencode($val)."&";
return trim($data, "&");
return $args;
// uuid generator
function create_guid(){
$microTime = microtime();
list($a_dec, $a_sec) = explode(" ", $microTime);
$dec_hex = dechex($a_dec* 1000000);
$sec_hex = dechex($a_sec);
ensure_length($dec_hex, 5);
ensure_length($sec_hex, 6);
$guid = "";
$guid .= $dec_hex;
$guid .= create_guid_section(3);
$guid .= '-';
$guid .= create_guid_section(4);
$guid .= '-';
$guid .= create_guid_section(4);
$guid .= '-';
$guid .= create_guid_section(4);
$guid .= '-';
$guid .= $sec_hex;
$guid .= create_guid_section(6);
return $guid;
function truncate($q) {
$len = abslength($q);
return $len <= 20 ? $q : (mb_substr($q, 0, 10) . $len . mb_substr($q, $len - 10, $len));
function abslength($str)
if(empty($str)){
return 0;
if(function_exists('mb_strlen')){
return mb_strlen($str,'utf-8');
else {
preg_match_all("/./u", $str, $ar);
return count($ar[0]);
function ensure_length(&$string, $length){
$strlen = strlen($string);
if($strlen < $length)
$string = str_pad($string, $length, "0");
else if($strlen > $length)
$string = substr($string, 0, $length);
function create_guid_section($characters){
$return = "";
for($i = 0; $i < $characters; $i++)
$return .= dechex(mt_rand(0,15));
return $return;
// 输入
upload();
query();
download();