腾讯云 人脸识别 人脸对比 v3 签名
程序员文章站
2022-03-06 13:18:26
...
调用 对比用的图片自己调整方法即可,此处写死
$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; }
结果