ALIYUN(阿里云)API 签名以及OCR调用
阿里云提供了部分免费的API使用次数,如OCR识别,机器翻译等。同时阿里云给出了一些代码的SDK供使用者调用这些API,本人主要使用的QT C++语言,无奈任何平台几乎都不会有完整的C++ SDK,最通用的调用就是通过平台的API接口。
阿里云的API接口不同于其他云平台的接口设计,其他云平台的接口只需要将内容拼接完成就可以直接GET或者POST,但是阿里云需要进行平台签名,将签名附带在请求中才可以,经过多次与阿里云工单沟通,先将完整的过程分享出来,供大家参考。
本案例包括阿里云的OCR与机器翻译操作过程
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMap>
#include <QByteArray>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_OCR_clicked();
QString in_urlEncode(QString strEncode);
QString in_ocrStrToSign(QString httpMethod);
QString computeHMACSHA1AndBase64(QByteArray key, QByteArray baseString);
void on_pushButton_trans_clicked();
private:
Ui::MainWindow *ui;
QMap<QString,QString> signMap;
QString ak_id = "your id";
QString ak_secret = "your secret";
};
#endif
```cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QDebug>
#include <QFile>
#include <QUuid>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_OCR_clicked()
{
QLocale lo = QLocale::English;
QString timestamp = lo.toString(QDateTime::currentDateTimeUtc(),"yyyy-MM-ddTHH:mm:ssZ");
QUuid id = QUuid::createUuid();
QString uuid = id.toString().remove("{").remove("}");
QString action = "RecognizeGeneral";
QString format = "JSON";
QString version = "2021-07-07";
QString http = "http://ocr-api.cn-hangzhou.aliyuncs.com/?";
signMap.insert("AccessKeyId",ak_id);
signMap.insert("Action",action);
signMap.insert("Format",format);
signMap.insert("Timestamp",timestamp);
signMap.insert("SignatureNonce",uuid);
signMap.insert("Version",version);
signMap.insert("SignatureMethod","HMAC-SHA1");
signMap.insert("SignatureVersion","1.0");
QString postString = in_ocrStrToSign("POST&%2F&");
QNetworkAccessManager *aliyun_Manager = new QNetworkAccessManager();
QNetworkRequest req;
req.setRawHeader("Content-Type", "application/octet-stream");
req.setUrl(http+postString);
QFile *file = new QFile();
file->setFileName("D:/Desktop/OCR/trans.PNG");
if (!file->open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open the file:" << file->errorString();
} else {
QNetworkReply* reply =aliyun_Manager->post(req, file);
QEventLoop eventLoop;
connect(aliyun_Manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
eventLoop.exec();
do
{
QApplication::processEvents(QEventLoop::AllEvents, 10);
}while(!reply->isFinished());
if(reply->isFinished())
{
QByteArray responseData;
responseData = reply->readAll();
qDebug()<<responseData;
}
}
}
QString MainWindow::in_urlEncode(QString strEncode)
{
QString safeCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~";
QByteArray encodedData = QUrl::toPercentEncoding(strEncode, safeCharacters.toUtf8());
QString encodedString = QString::fromUtf8(encodedData);
return encodedString;
}
QString MainWindow::in_ocrStrToSign(QString httpMethod)
{
QString stringToSign;
for (auto it = signMap.constBegin(); it != signMap.constEnd(); ++it)
{
stringToSign += it.key() + "=" + in_urlEncode(it.value()) + "&";
}
if (!stringToSign.isEmpty()) {
stringToSign.chop(1);
}
stringToSign = in_urlEncode(stringToSign);
stringToSign =httpMethod+stringToSign;
QString signature = computeHMACSHA1AndBase64(QString(ak_secret+"&").toLocal8Bit(),stringToSign.toLocal8Bit());
signature = in_urlEncode(signature);
signMap.insert("Signature",signature);
QString httpString;
for (auto it = signMap.constBegin(); it != signMap.constEnd(); ++it)
{
httpString += it.key() + "=" + it.value() + "&";
}
if (! httpString.isEmpty()) {
httpString.chop(1);
}
return httpString;
}
QString MainWindow::computeHMACSHA1AndBase64(QByteArray key, QByteArray baseString)
{
int blockSize = 64;
if (key.length() > blockSize) {
key = QCryptographicHash::hash(key, QCryptographicHash::Sha1);
}
QByteArray innerPadding(blockSize, char(0x36));
QByteArray outerPadding(blockSize, char(0x5c));
for (int i = 0; i < key.length(); i++) {
innerPadding[i] = innerPadding[i] ^ key.at(i);
outerPadding[i] = outerPadding[i] ^ key.at(i);
}
QByteArray total = outerPadding;
QByteArray part = innerPadding;
part.append(baseString);
total.append(QCryptographicHash::hash(part, QCryptographicHash::Sha1));
QByteArray hashed = QCryptographicHash::hash(total, QCryptographicHash::Sha1);
return hashed.toBase64();
}
void MainWindow::on_pushButton_trans_clicked()
{
QLocale lo = QLocale::English;
QString timestamp = lo.toString(QDateTime::currentDateTimeUtc(),"yyyy-MM-ddTHH:mm:ssZ");
QUuid id = QUuid::createUuid();
QString uuid = id.toString().remove("{").remove("}");
QString action = "RecognizeGeneral";
QString version = "2021-07-07";
QString format = "JSON";
QString http = "http://ocr-api.cn-hangzhou.aliyuncs.com/?";
QString FormatType = "text";
version = "2018-10-12";
action = "TranslateGeneral";
http =" http://mt.cn-hangzhou.aliyuncs.com/?";
signMap.insert("AccessKeyId",ak_id);
signMap.insert("Action",action);
signMap.insert("Timestamp",timestamp);
signMap.insert("SignatureNonce",uuid);
signMap.insert("Version",version);
signMap.insert("SignatureMethod","HMAC-SHA1");
signMap.insert("SignatureVersion","1.0");
signMap.insert("FormatType",FormatType);
signMap.insert("Scene","general");
signMap.insert("SourceLanguage","zh");
signMap.insert("SourceText","你好");
signMap.insert("TargetLanguage","en");
signMap.insert("Format",format);
QString postString = in_ocrStrToSign("GET&%2F&");
QString httpstr = "http://mt.cn-hangzhou.aliyuncs.com/?Action=TranslateGeneral&FormatType=text"
"&Scene=general&SourceLanguage=zh&SourceText=你好&TargetLanguage=en&"+postString;
qDebug()<<httpstr;
QNetworkAccessManager *aliyun_Manager = new QNetworkAccessManager();
QNetworkRequest req;
req.setUrl(httpstr);
QNetworkReply* reply =aliyun_Manager->get(req);
QEventLoop eventLoop;
connect(aliyun_Manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
eventLoop.exec();
do
{
QApplication::processEvents(QEventLoop::AllEvents, 10);
}while(!reply->isFinished());
if(reply->isFinished())
{
QByteArray responseData;
responseData = reply->readAll();
qDebug()<<responseData;
}
}