博主信息
朝游东海
博文
43
粉丝
2
评论
2
访问量
73402
积分:3
P豆:837

腾讯云 人脸识别 人脸对比 v3 签名

2020年07月07日 11:07:34阅读数:474博客 / 朝游东海/ tp5

调用  对比用的图片自己调整方法即可,此处写死

        $logic = new \app\common\logic\TencentPictureContrastLogic();
        p($logic->contrast());

封装方法

<?php
namespace app\common\logic;

/**
 * 腾讯云图片对比逻辑层
 * @author 朝游东海
 * 官方文档
 * https://cloud.tencent.com/document/product/867/32772
 * https://cloud.tencent.com/document/product/867/32802
*/

class TencentPictureContrastLogic 
{

    private $requestDomain = 'https://iai.ap-chengdu.tencentcloudapi.com' ;  //请求域名
    private $header;
    private $secretId = '';  //用于标识 API 调用者身份,可以简单类比为用户名。 本文使用的安全凭证为密钥,密钥包括 SecretId 和 SecretKey。每个用户最多可以拥有两对密钥。
    private $secretKey = ''; //用于验证 API 调用者的身份,可以简单类比为密码。 申请安全凭证
    private $host = 'iai.tencentcloudapi.com';
    private $server = 'iai';
    private $version = '2018-03-01'; // '2020-03-03'; //
    private $action = 'CompareFace';
    private $region = 'ap-chengdu';
    private $timestamp;
    private $algorithm = 'TC3-HMAC-SHA256';
    private $canonicalHeaders;
    private $signedHeaders;
    private $canonicalRequest = '';
    private $stringToSign = '';
    private $credentialScope; //凭证范围
    private $signature; //计算签名
    private $authorization;




    /**
     * 图片对比
    */
    public function contrast()
    {
        $this->setCommonRequestHeader(); //设置请求公共头
        $this->setCanonicalHeaders();
        $this->setSignedHeaders();
        $this->setCanonicalRequest();  //接规范请求串
        $this->setSplitSign(); //拼接待签名字符串
        $this->setSign(); //计算签名
        $this->setAuthorization(); //拼接 Authorization
        return $this->curlRequest();
    }


    //设置公共参数
    private function setCommonRequestHeader()
    {
        $this->timestamp = time();
        $this->header = [
            'Content-Type'=>'application/json; charset=utf-8', //application/x-www-form-urlencoded
            'Host'=>$this->host,
            'X-TC-Action'=>$this->action,
            'X-TC-Timestamp'=> $this->timestamp,
            'X-TC-Version'=>$this->version,
            'X-TC-Region'=>$this->region,
            'SignatureMethod'=>$this->algorithm
        ];
    }



    /**
     * step 1: build canonical request string
     * 获取拼接规范请求穿
     * https://cloud.tencent.com/document/api/867/32774
    */
    private function setCanonicalRequest()
    {
        $httpRequestMethod = "POST";
        $canonicalUri = "/";
        $canonicalQueryString = "";
        $canonicalHeaders = $this->canonicalHeaders;
        $signedHeaders = $this->signedHeaders;
        //$payload = '{"Limit": 1, "Filters": [{"Values": ["\u672a\u547d\u540d"], "Name": "instance-name"}]}';
        $payload = json_encode($this->setHashedRequestPayload());
        $hashedRequestPayload = hash("SHA256", $payload);
        $canonicalRequest = $httpRequestMethod."\n"
            .$canonicalUri."\n"
            .$canonicalQueryString."\n"
            .$canonicalHeaders."\n"
            .$signedHeaders."\n"
            .$hashedRequestPayload;
        $this->canonicalRequest =$canonicalRequest;
    }


    /**
     * 参与签名的头部信息,至少包含 host 和 content-type 两个头部,也可加入自定义的头部参与签名以提高自身请求的唯一性和安全性。
     *拼接规则:
     *  头部 key 和 value 统一转成小写,并去掉首尾空格,按照 key:value\n 格式拼接;
     *  多个头部,按照头部 key(小写)的 ASCII 升序进行拼接。
    */
    private function setCanonicalHeaders()
    {
        $tmp = $tmp1 = [];
        foreach( $this->header as $k=>$v ){
            $tmp[strtolower(trim($k))] = strtolower(trim($v));
        }
        ksort($tmp);
        $srt = '';
        foreach($tmp as $k=>$v){
            $srt .= $k.':'.$v."\n";
        }
        $this->canonicalHeaders = $srt;
    }

    /**
     * 参与签名的头部信息,说明此次请求有哪些头部参与了签名,和 CanonicalHeaders 包含的头部内容是一一对应的。content-type 和 host 为必选头部。
     *拼接规则:
     *   头部 key 统一转成小写;
     *  多个头部 key(小写)按照 ASCII 升序进行拼接,并且以分号(;)分隔。
     *   此示例为 content-type;host
    */
    private function setSignedHeaders()
    {
        $tmpdd = $tmp1 = [];
        foreach( $this->header as $k=>$v ){
            $tmpdd[strtolower(trim($k))] = strtolower(trim($v));
        }
        ksort($tmpdd);
        $keys = array_keys($tmpdd);
        $srt = '';
        foreach($keys as $k=>$v){
            $srt .= $v.';';
        }
        $reqPar = '';
        if (strlen($srt) > 0) {
            $reqPar = substr($srt, 0, strlen($srt) - 1);
        }
        $this->signedHeaders = $reqPar;
    }


    private function setHashedRequestPayload()
    {
        //同一脸
        $a='http://xcx.wqzydh.cn/uploads/imgs/20200707/d362d2ee5a235c7798c04f8524a1a5b7.png'; //同一脸,小,笑
        $b='http://xcx.wqzydh.cn/uploads/imgs/20200707/a9e33641c3a75e6828440c74cbd820c6.png'; //同一脸,小,不笑,下图为放大版
        $d='http://xcx.wqzydh.cn/uploads/imgs/20200707/a9e33641c3a75e6828440c74cbd820c6.png'; //同一脸,大,不笑
        //非同一脸
        $c = 'http://xcx.wqzydh.cn/uploads/imgs/20200707/f252f252ec4cd7c59c1a9b7d502391de.jpg';
        //表情包
        $f = 'http://xcx.wqzydh.cn/uploads/imgs/20190628/e6ad5e295f849cdb9a8439f609ae6896.jpg';
        $requsetArr = [
            'UrlA'=>$a,
            'UrlB'=>$b,
        ];
        return $requsetArr;
    }

     /**
      * step 2: build string to sign
      * 拼接待签名字符串
     */
    private function setSplitSign()
    {
        $date = gmdate("Y-m-d", $this->timestamp);
        $this->credentialScope = $date."/".$this->server."/tc3_request";
        $hashedCanonicalRequest = hash("SHA256", $this->canonicalRequest);
        $stringToSign = $this->algorithm."\n"
            .$this->timestamp."\n"
            .$this->credentialScope."\n"
            .$hashedCanonicalRequest;
        $this->stringToSign = $stringToSign;
    }

    /**
     *    step 3: sign string
     *  计算签名
    */
    private function setSign()
    {
        $secretDate = hash_hmac("SHA256", gmdate("Y-m-d", $this->timestamp), "TC3".$this->secretKey, true);
        $secretService = hash_hmac("SHA256", $this->server, $secretDate, true);
        $secretSigning = hash_hmac("SHA256", "tc3_request", $secretService, true);
        $signature = hash_hmac("SHA256", $this->stringToSign, $secretSigning);
        $this->signature = $signature;
    }

    /**
     *  step 4: build authorization
     * 拼接 Authorization
    */
    private function setAuthorization()
    {
        $authorization = $this->algorithm
            ." Credential=".$this->secretId."/".$this->credentialScope
            .", SignedHeaders=".$this->signedHeaders
        .", Signature=".$this->signature;
        $this->authorization = $authorization;
    }


    /**
     *  step 5: curl request
     * curl 请求
     */
    private function curlRequest()
    {
        $sortHeader = $this->sortHeader();
        $header = $this->curlNeedHeader(  $sortHeader );
        return json_decode(httpPost($this->requestDomain,json_encode($this->setHashedRequestPayload()),$header,true),true);
    }


    //把Authorization插入到数组头部
    private function sortHeader()
    {
        $sortArr['Authorization'] = $this->authorization;
        foreach($this->header as $k7=>$v7){
            $sortArr[$k7]=$v7;
        }
        return $sortArr;
    }


    /**
     * 组装curl 需要的header头
    */
    private function  curlNeedHeader($array = [])
    {
        $rel = [];
        foreach($array as $k=>$v){
            $rel[] = $k.':'.$v;
        }
        return $rel;
    }



}


补充方法

    /**
	 * curl发出Post请求
	 * @param string $url        
	 * @param json $data
     * @param array $headers
	 * @return
	 */
 function httpPost( $url, $data,$headers ) {
    $ch = curl_init();
    curl_setopt( $ch, CURLOPT_URL, $url );
    curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, "POST" );
    curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
    curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
    curl_setopt( $ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)" );
    curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 );
    curl_setopt( $ch, CURLOPT_AUTOREFERER, 1 );
    curl_setopt( $ch, CURLOPT_POSTFIELDS, $data );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    $tmpInfo = curl_exec( $ch );
    if ( curl_errno( $ch ) ) {return curl_error( $ch );}
    curl_close( $ch );
    return $tmpInfo;
}



/**
 * 传递数据以易于阅读的样式格式化后输出
 * @param array data|需要打印的数据
 * @return str str|格式化后的数据
 * ***/
function p($data){
    // 定义样式
    $str='<pre style="display: block;padding: 9.5px;margin: 44px 0 0 0;font-size: 13px;line-height: 1.42857;color: #333;word-break: break-all;word-wrap: break-word;background-color: #F5F5F5;border: 1px solid #CCC;border-radius: 4px;">';
    // 如果是boolean或者null直接显示文字;否则print
    if (is_bool($data)) {
        $show_data=$data ? 'true' : 'false';
    }elseif (is_null($data)) {
        $show_data='null';
    }else{
        $show_data=print_r($data,true);
    }
    $str.=$show_data;
    $str.='</pre>';
    echo $str;
}


结果

rel1.pngrel2.png



版权申明:本博文版权归博主所有,转载请注明地址!如有侵权、违法,请联系admin@php.cn举报处理!

全部评论

文明上网理性发言,请遵守新闻评论服务协议

条评论