ALIYUN(阿里云)API 签名以及OCR调用

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; //用于关键字的 key value配对
    QString ak_id  = "your id";
    QString ak_secret = "your secret";
};

#endif // MAINWINDOW_H

```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;//设置QLocale为英文
    //时间戳
    QString timestamp = lo.toString(QDateTime::currentDateTimeUtc(),"yyyy-MM-ddTHH:mm:ssZ");
    //生成随机数
    QUuid id = QUuid::createUuid();
    QString uuid = id.toString().remove("{").remove("}"); //获取UUid并去除左右括号
    QString action = "RecognizeGeneral";
    QString format = "JSON";
    QString version = "2021-07-07";
    QString http = "http://ocr-api.cn-hangzhou.aliyuncs.com/?";

// 按照阿里云的要求,将公共参数组装起来,如果识别的是在线图片如:Url=http://mycat.dg.png // 这个URl我随便写的,也需要将url这个公共参数,插入signMap进行前面个signMap.insert("Url","http://mycat.dg.png "); 注意HTTP方式徐采用GET方式
    //ocr ****************************
        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");
    //ocr*****************************
// 由于识别本地图片,所以采用POST
//in_ocrStrToSign  这个函数用来签名 
        QString postString = in_ocrStrToSign("POST&%2F&");
        QNetworkAccessManager *aliyun_Manager = new   QNetworkAccessManager();//后需要连接以下槽函数
        QNetworkRequest req;
        req.setRawHeader("Content-Type", "application/octet-stream");

        //设置url
        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 {
            // Send the POST request with the file as the request body
            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-_.~";

    // 使用QUrl::toPercentEncoding对字符串进行编码
    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)
    {
        //将signMpa里面的数据拼接起来,同时对value值进行URLENCODE编码
        stringToSign += it.key() + "=" + in_urlEncode(it.value()) + "&";
    }
    // 去掉最后一个'&'
    if (!stringToSign.isEmpty()) {
        stringToSign.chop(1);
    }
    // 把拼接好的url再次转码
    stringToSign = in_urlEncode(stringToSign);
    // url转码后拼接method方式
    stringToSign =httpMethod+stringToSign;
    // 获得签名
    QString signature = computeHMACSHA1AndBase64(QString(ak_secret+"&").toLocal8Bit(),stringToSign.toLocal8Bit());
    // 签名URL编码
    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; // HMAC-SHA-1 block size, defined in SHA-1 standard
    if (key.length() > blockSize) { // if key is longer than block size (64), reduce key length with SHA-1 compression
        key = QCryptographicHash::hash(key, QCryptographicHash::Sha1);
    }
    QByteArray innerPadding(blockSize, char(0x36)); // initialize inner padding with char"6"
    QByteArray outerPadding(blockSize, char(0x5c)); // initialize outer padding with char"/"
    // ascii characters 0x36 ("6") and 0x5c ("/") are selected because they have large
    // Hamming distance (http://en.wikipedia.org/wiki/Hamming_distance)
    for (int i = 0; i < key.length(); i++) {
        innerPadding[i] = innerPadding[i] ^ key.at(i); // XOR operation between every byte in key and innerpadding, of key length
        outerPadding[i] = outerPadding[i] ^ key.at(i); // XOR operation between every byte in key and outerpadding, of key length
    }
    // result = hash ( outerPadding CONCAT hash ( innerPadding CONCAT baseString ) ).toBase64
    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()
{
   //本部分为机器翻译API,过程和OCR一致,唯一的区别在于需要将请求字符串中的所有参数都需要进行URL编码,具体看signmap里面的内容
    QLocale lo = QLocale::English;//设置QLocale为英文
    QString timestamp = lo.toString(QDateTime::currentDateTimeUtc(),"yyyy-MM-ddTHH:mm:ssZ");
    //生成随机数
    QUuid id = QUuid::createUuid();
    QString uuid = id.toString().remove("{").remove("}"); //获取UUid并去除左右括号

    QString action = "RecognizeGeneral";
    QString version = "2021-07-07";
    QString format = "JSON";
    QString http = "http://ocr-api.cn-hangzhou.aliyuncs.com/?";

    //trans ***********************
    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;
    //    //设置url
    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;
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大头鼹鼠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值