基于C++Qt5通过调用百度翻译API制作简易翻译工具
目录
写在前面
先看看效果图
机缘巧合我发现了百度翻译API,也看了很多大佬用这个API做的项目。恰我的C++实验课的大作业是做一个项目,我就想到了做一个简易的翻译工具。
实现方法:通过封装一个生成url的类,对传入的需要翻译的内容生产相应的url,然会用QNetworkRequest类发送get请求,对请求返回的结果正则表达式解析和utf-8转码就得到了翻译结果
注意:翻译记录功能目前还没实现,不是因为很难,是因为很懒
步骤:
1.注册百度翻译开放平台账号并开通翻译服务
进入百度翻译开放平台官网,登录或注册
开通翻译服务
这里应该还要求实名认证才能开通服务
获取appid和密钥
2.下载安装Qt5和QtCreator (windows)
2.1下载Qt5
Qt5可以去下面的网站下载
[https://download.qt.io/archive/qt/]
(https://download.qt.io/archive/qt/)
也可以用迅雷下载我下载好的Qt5.12.10
链接:https://pan.xunlei.com/s/VMT-alRj3yvgWqrYNgWSPYeJA1
提取码:5b9p
2.2安装Qt5和QtCreator
注册后他会发邮件给你,按照它提示的步骤完成就行,我就不演示了,注册好后再回来。
接下来是选配环节了,建议电脑内存充足的选择全选,说不定以后能用上
下面的选择是安装Qtcreator
配置完成后点击下一步,来到下面的界面
这个安装要挺久的,反正我装了30分钟才装好。
装好之后在wimdows菜单找到刚刚创建的那个文件夹拉到最下面,如下图
到这里Qt5算是装好了,可以开始创建我们的项目了
2.3创建项目
打开QtCreator后
选择创建新项目
创建完成后
跑不了的可以按步骤再多试几次
最后按下面的步骤添加
QT += network
这是访问必须的配置
到这里创建项目的准备工作就完成了
3.封装生成Url类
3.1百度翻译文档阅读
如果还没看过百度翻译api的文档建议先去看看,了解url的生产有助于下面代码的理解
百度翻译api文档
3.2编写代码
以下是实现生产url类的源码
Translator.h
#ifndef TANSLATOR_H
#define TANSLATOR_H
#include <iostream>
#include <QString>
#include <time.h>
#include <QTextCodec>
#include <QDebug>
#include <QObject>
#include "MD5.h"
using namespace std;
class Translator: public QObject
{
Q_OBJECT
private:
//支持7个翻译目标语种的标号
string lan[7]={
"en","zh","fra","de","kor","jp","th"};
int index; //选择语种的下标
/* 因为百度翻译需要一个MD5加密的签名
* 但是我找到的MD5加密的方法都只支持string类型
* 所以这里先生产string类型url再转成Qstring
* ps:不知道string和Qstring的区别可以去补一下课*/
string myurl; //存放string类型url
string appid; //appid
QString qstr; //传入的Qstring类型翻译的内容,需要转成string类型
string q; //string类型翻译的内容
string from; //翻译内容的语种,一般为‘auto’
string to; //翻译目标语种
string salt; //一串随机数,我是用时间戳当成随机数
string secret_key; //密钥
string sign; //MD5加密的签名
QString url; //Qstring类型url
public:
Translator(); //默认构造函数
Translator(const QString &); //构造函数
QString GetUrl(); //生产url的方法
void SetQstr(const QString &); //设置需要翻译内容的函数
void SetIndex(const int&); //设置翻译目标语种的函数
};
#endif // TANSLATOR_H
Translator.cpp
#include "Translator.h"
#if _MSC_VER >=1600 // MSVC2015>1899,对于MSVC2010以上版本都可以使用
#pragma execution_character_set("utf-8")
#endif
Translator::Translator(){
}
Translator::Translator(const QString &qerry)
:qstr(qerry)
{
q = qstr.toStdString();
index = 0;
}
void Translator::SetQstr(const QString &qstring){
qstr = qstring;
q = qstr.toStdString();
}
void Translator::SetIndex(const int& in){
index = in;
}
QString Translator::GetUrl(){
//制作签名
myurl = "https://fanyi-api.baidu.com/api/trans/vip/translate?";
appid = "1212121212"; //你的appid
from = "auto";
to = lan[index]; //选择目标语种
time_t myt = time(NULL); //获取时间戳
salt = to_string(myt);
secret_key = "12121212212"; //你的密钥
sign = "";
//签名拼接
sign.append(appid);
sign.append(q);
sign.append(salt);
sign.append(secret_key);
//签名MD5加密
MD5 md5 = MD5(sign);
sign = md5.outstr(32).c_str();
//制作url
myurl.append("&q=");
myurl.append(q);
myurl.append("&from=");
myurl.append(from);
myurl.append("&to=");
myurl.append(to);
myurl.append("&appid=");
myurl.append(appid);
myurl.append("&salt=");
myurl.append(salt);
myurl.append("&sign=");
myurl.append(sign);
//string转Qstring
url=QString::fromStdString(myurl);
return url;
}
下面附上MD5加密的源码,来源于网络
MD5.h
#include <iostream>
#include <windows.h>
using namespace std;
typedef unsigned char uchar;
typedef unsigned long ulong;
//步函数
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
//循环左移
#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
// 四轮操作
#define FF(a, b, c, d, mj, s, ti) { (a) += F ((b), (c), (d)) + (mj) + ti; (a) = ROL ((a), (s)); (a) += (b);}
#define GG(a, b, c, d, mj, s, ti) { (a) += G ((b), (c), (d)) + (mj) + ti; (a) = ROL ((a), (s)); (a) += (b);}
#define HH(a, b, c, d, mj, s, ti) { (a) += H ((b), (c), (d)) + (mj) + ti; (a) = ROL ((a), (s)); (a) += (b);}
#define II(a, b, c, d, mj, s, ti) { (a) += I ((b), (c), (d)) + (mj) + ti; (a) = ROL ((a), (s)); (a) += (b);}
class MD5 {
public:
MD5(const string& str);
const uchar* getDigest(); // 获取生成的摘要
string outstr(int); // 返回字符串
private:
void generate(const uchar* input, int length);
void change(const uchar block[64]); // 四轮操作
void encode(const ulong* input, uchar* output, int length); // uchar to ulong
void decode(const uchar* input, ulong* output, int length); // ulong to uchar
ulong reg[4]; // ABCD
ulong count[2]; // 长度扩充
uchar buffer[64]; // 输入buffer
uchar digest[16]; // 生成的摘要
bool end_flag; // 结束标志
static const uchar padding[64];
static const char hex[16];
};
MD5.cpp
#include <MD5.h>
const uchar MD5::padding[64] = {
0x80 }; // 初始化附加填充 1000 0000, 设置最高位为1
const char MD5::hex[16] = {
'0', '1', '2', '3','4', '5', '6', '7','8', '9', 'a', 'b','c', 'd', 'e', 'f' };
MD5::MD5(const string& str) {
end_flag = false;
count[0] = count[1] = 0; // 重置bits个数
// 初始化链接变量(高位->低位)
/*
* 错误的赋值,注意高低位
reg[0] = 0x01234567;
reg[1] = 0x89abcdef;
reg[2] = 0xfedcba98;
reg[3] = 0x76543210;
*/
reg[0] = 0x67452301;
reg[1] = 0xefcdab89;
reg[2] = 0x98badcfe;
reg[3] = 0x10325476;
generate((uchar*)const_cast<char*>(str.c_str()), str.length());
}
/**
* 获取摘要
*/
const uchar* MD5::getDigest() {
if (!end_flag) {
end_flag = true;
uchar bits[8];
ulong _reg[4]; // 旧reg
ulong _count[2]; // 旧count
ulong index, padLen;
memcpy(_reg, reg, 16); // 复制内存,将_reg内存地址的起始位置开始拷贝16字节到reg起始位置中
memcpy(_count, count, 8); // 将原始消息长度以64比特(8字节)复制到count后
encode(count, bits, 8);
/* Pad out to 56 mod 64. */
index = (ulong)((count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
generate(padding, padLen);
generate(bits, 8);
encode(reg, digest, 16);
/* 重新存储reg和count */
memcpy(reg, _reg, 16);
memcpy(count, _count, 8);
}
return digest;
}
void MD5::generate(const uchar* input, int length) {
ulong i, index, partLen;
end_flag = false;
index = (ulong)((count[0] >> 3) & 0x3f);
if ((count[