开放能力
开发平台
行业应用
生态合作
开发与教学
资讯 社区 控制台
技术能力
语音技术
图像技术
文字识别
人脸与人体识别
视频技术
AR与VR
自然语言处理
知识图谱
数据智能
场景方案
部署方案
行业应用
智能教育
智能医疗
智能零售
智能工业
企业服务
智能政务
智能农业
信息服务
智能园区
智能硬件
文字识别

    身份证识别

    接口描述

    支持对二代居民身份证正反面所有8个字段进行结构化识别,包括姓名、性别、民族、出生日期、住址、身份证号、签发机关、有效期限,识别准确率超过99%;同时支持身份证正面头像检测,并返回头像切片的base64编码及位置信息。

    同时,支持对用户上传的身份证图片进行图像风险和质量检测,可识别图片是否为复印件或临时身份证,是否被翻拍或编辑,是否存在正反颠倒、模糊、欠曝、过曝等质量问题。

    增值能力 详情
    裁剪能力 头像检测与切片:返回头像切片的base64编码及位置信息
    质量检测 身份证图片模糊检测
    身份证关键字段反光或过曝光
    身份证图片较暗或欠曝光
    风险检测 身份证复印件告警
    临时身份证告警
    身份证翻拍告警
    身份证PS编辑告警
    身份证证号不合法告警
    身份证证号和姓名、出生日期、性别信息不一致告警

    在线调试

    您可以在 API Explorer 中调试该接口,可进行签名验证、查看在线调用的请求内容和返回结果、示例代码的自动生成。

    请求说明

    请求示例

    HTTP 方法:POST

    请求URL: https://aip.baidubce.com/rest/2.0/ocr/v1/idcard

    URL参数:

    参数
    access_token 通过API Key和Secret Key获取的access_token,参考“Access Token获取

    Header如下:

    参数
    Content-Type application/x-www-form-urlencoded

    Body中放置请求参数,参数详情如下:

    请求参数

    参数 是否必选 类型 可选值范围 说明
    image 和url二选一 string - 图像数据,base64编码后进行urlencode,要求base64编码和urlencode后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/jpeg/png/bmp格式
    url 和image二选一 string - 图片完整URL,URL长度不超过1024字节,URL对应的图片base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/jpeg/png/bmp格式,当image字段存在时url字段失效
    请注意关闭URL防盗链
    id_card_side string front/back -front:身份证含照片的一面
    -back:身份证带国徽的一面
    自动检测身份证正反面,如果传参指定方向与图片相反,支持正常识别,返回参数image_status字段为"reversed_side"
    detect_risk string true/false 是否开启身份证风险类型(身份证复印件、临时身份证、身份证翻拍、修改过的身份证)功能,默认不开启,即:false。
    - true:开启,请查看返回参数risk_type;
    - false:不开启
    detect_photo string true/false 是否检测头像内容,默认不检测。可选值:true-检测头像并返回头像的 base64 编码及位置信息

    请求代码示例

    提示一:使用示例代码前,请记得替换其中的示例Token、图片地址或Base64信息。

    提示二:部分语言依赖的类或库,请在代码注释中查看下载地址。

    curl -i -k 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=【调用鉴权接口获取的token】' --data 'id_card_side=front&image=【图片Base64编码,需UrlEncode】' -H 'Content-Type:application/x-www-form-urlencoded'
    # encoding:utf-8
    
    import requests
    import base64
    
    '''
    身份证识别
    '''
    
    request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard"
    # 二进制方式打开图片文件
    f = open('[本地文件]', 'rb')
    img = base64.b64encode(f.read())
    
    params = {"id_card_side":"front","image":img}
    access_token = '[调用鉴权接口获取的token]'
    request_url = request_url + "?access_token=" + access_token
    headers = {'content-type': 'application/x-www-form-urlencoded'}
    response = requests.post(request_url, data=params, headers=headers)
    if response:
        print (response.json())
    package com.baidu.ai.aip;
    
    import com.baidu.ai.aip.utils.Base64Util;
    import com.baidu.ai.aip.utils.FileUtil;
    import com.baidu.ai.aip.utils.HttpUtil;
    
    import java.net.URLEncoder;
    
    /**
    * 身份证识别
    */
    public class Idcard {
    
        /**
        * 重要提示代码中所需工具类
        * FileUtil,Base64Util,HttpUtil,GsonUtils请从
        * https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
        * https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
        * https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
        * https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
        * 下载
        */
        public static String idcard() {
            // 请求url
            String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
            try {
                // 本地文件路径
                String filePath = "[本地文件路径]";
                byte[] imgData = FileUtil.readFileByBytes(filePath);
                String imgStr = Base64Util.encode(imgData);
                String imgParam = URLEncoder.encode(imgStr, "UTF-8");
    
                String param = "id_card_side=" + "front" + "&image=" + imgParam;
    
                // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
                String accessToken = "[调用鉴权接口获取的token]";
    
                String result = HttpUtil.post(url, accessToken, param);
                System.out.println(result);
                return result;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        public static void main(String[] args) {
            Idcard.idcard();
        }
    }
    #include <iostream>
    #include <curl/curl.h>
    
    // libcurl库下载链接:https://curl.haxx.se/download.html
    // jsoncpp库下载链接:https://github.com/open-source-parsers/jsoncpp/
    const static std::string request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
    static std::string idcard_result;
    /**
     * curl发送http请求调用的回调函数,回调函数中对返回的json格式的body进行了解析,解析结果储存在全局的静态变量当中
     * @param 参数定义见libcurl文档
     * @return 返回值定义见libcurl文档
     */
    static size_t callback(void *ptr, size_t size, size_t nmemb, void *stream) {
        // 获取到的body存放在ptr中,先将其转换为string格式
        idcard_result = std::string((char *) ptr, size * nmemb);
        return size * nmemb;
    }
    /**
     * 身份证识别
     * @return 调用成功返回0,发生错误返回其他错误码
     */
    int idcard(std::string &json_result, const std::string &access_token) {
        std::string url = request_url + "?access_token=" + access_token;
        CURL *curl = NULL;
        CURLcode result_code;
        int is_success;
        curl = curl_easy_init();
        if (curl) {
            curl_easy_setopt(curl, CURLOPT_URL, url.data());
            curl_easy_setopt(curl, CURLOPT_POST, 1);
            curl_httppost *post = NULL;
            curl_httppost *last = NULL;
            curl_formadd(&post, &last, CURLFORM_COPYNAME, "id_card_side", CURLFORM_COPYCONTENTS, "front", CURLFORM_END);
            curl_formadd(&post, &last, CURLFORM_COPYNAME, "image", CURLFORM_COPYCONTENTS, "【base64_img】", CURLFORM_END);
    
            curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
            result_code = curl_easy_perform(curl);
            if (result_code != CURLE_OK) {
                fprintf(stderr, "curl_easy_perform() failed: %s\n",
                        curl_easy_strerror(result_code));
                is_success = 1;
                return is_success;
            }
            json_result = idcard_result;
            curl_easy_cleanup(curl);
            is_success = 0;
        } else {
            fprintf(stderr, "curl_easy_init() failed.");
            is_success = 1;
        }
        return is_success;
    }
    <?php
    /**
     * 发起http post请求(REST API), 并获取REST请求的结果
     * @param string $url
     * @param string $param
     * @return - http response body if succeeds, else false.
     */
    function request_post($url = '', $param = '')
    {
        if (empty($url) || empty($param)) {
            return false;
        }
    
        $postUrl = $url;
        $curlPost = $param;
        // 初始化curl
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $postUrl);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        // 要求结果为字符串且输出到屏幕上
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        // post提交方式
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
        // 运行curl
        $data = curl_exec($curl);
        curl_close($curl);
    
        return $data;
    }
    
    $token = '[调用鉴权接口获取的token]';
    $url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=' . $token;
    $img = file_get_contents('[本地文件路径]');
    $img = base64_encode($img);
    $bodys = array(
        'id_card_side' => "front",
        'image' => $img
    );
    $res = request_post($url, $bodys);
    
    var_dump($res);
    using System;
    using System.IO;
    using System.Net;
    using System.Text;
    using System.Web;
    
    namespace com.baidu.ai
    {
        public class Idcard
        {
            // 身份证识别
            public static string idcard()
            {
                string token = "[调用鉴权接口获取的token]";
                string host = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + token;
                Encoding encoding = Encoding.Default;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host);
                request.Method = "post";
                request.KeepAlive = true;
                // 图片的base64编码
                string base64 = getFileBase64("[本地图片文件]");
                String str = "id_card_side=" + "front" + "&image=" + HttpUtility.UrlEncode(base64);
                byte[] buffer = encoding.GetBytes(str);
                request.ContentLength = buffer.Length;
                request.GetRequestStream().Write(buffer, 0, buffer.Length);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
                string result = reader.ReadToEnd();
                Console.WriteLine("身份证识别:");
                Console.WriteLine(result);
                return result;
            }
    
            public static String getFileBase64(String fileName) {
                FileStream filestream = new FileStream(fileName, FileMode.Open);
                byte[] arr = new byte[filestream.Length];
                filestream.Read(arr, 0, (int)filestream.Length);
                string baser64 = Convert.ToBase64String(arr);
                filestream.Close();
                return baser64;
            }
        }
    }

    返回说明

    返回参数

    字段 是否必选 类型 说明
    direction int32 图像方向,当图像旋转时,返回该参数。
    - - 1:未定义,
    - 0:正向,
    - 1:逆时针90度,
    - 2:逆时针180度,
    - 3:逆时针270度
    image_status string normal-识别正常
    reversed_side-身份证正反面颠倒
    non_idcard-上传的图片中不包含身份证
    blurred-身份证模糊
    other_type_card-其他类型证照
    over_exposure-身份证关键字段反光或过曝
    over_dark-身份证欠曝(亮度过低)
    unknown-未知状态
    risk_type string 输入参数 detect_risk = true 时,则返回该字段识别身份证类型: normal-正常身份证;copy-复印件;temporary-临时身份证;screen-翻拍;unknown-其他未知情况
    edit_tool string 如果参数 detect_risk = true 时,则返回此字段。如果检测身份证被编辑过,该字段指定编辑软件名称,如:Adobe Photoshop CC 2014 (Macintosh),如果没有被编辑过则返回值无此参数
    log_id uint64 唯一的log id,用于问题定位
    photo string 当请求参数 detect_photo = true时返回,头像切图的 base64 编码(无编码头,需自行处理)
    photo_location array[] 当请求参数 detect_photo = true时返回,头像的位置信息(坐标0点为左上角)
    idcard_number_type string 用于校验身份证号码、性别、出生是否一致,输出结果及其对应关系如下:
    - 1: 身份证正面所有字段全为空
    0: 身份证证号不合法,此情况下不返回身份证证号
    1: 身份证证号和性别、出生信息一致
    2: 身份证证号和性别、出生信息都不一致
    3: 身份证证号和出生信息不一致
    4: 身份证证号和性别信息不一致
    words_result array[] 定位和识别结果数组
    words_result_num uint32 识别结果数,表示words_result的元素个数
    + location array[] 位置数组(坐标0点为左上角)
    ++ left uint32 表示定位位置的长方形左上顶点的水平坐标
    ++ top uint32 表示定位位置的长方形左上顶点的垂直坐标
    ++ width uint32 表示定位位置的长方形的宽度
    ++ height uint32 表示定位位置的长方形的高度
    + words string 识别结果字符串

    返回示例

    {
        "log_id": 2648325511,
        "direction": 0,
        "image_status": "normal",
        "photo": "/9j/4AAQSkZJRgABA......",
        "photo_location": {
            "width": 1189,
            "top": 638,
            "left": 2248,
            "height": 1483
        },
        "words_result": {
            "住址": {
                "location": {
                    "left": 267,
                    "top": 453,
                    "width": 459,
                    "height": 99
                },
                "words": "南京市江宁区弘景大道3889号"
            },
            "公民身份号码": {
                "location": {
                    "left": 443,
                    "top": 681,
                    "width": 589,
                    "height": 45
                },
                "words": "330881199904173914"
            },
            "出生": {
                "location": {
                    "left": 270,
                    "top": 355,
                    "width": 357,
                    "height": 45
                },
                "words": "19990417"
            },
            "姓名": {
                "location": {
                    "left": 267,
                    "top": 176,
                    "width": 152,
                    "height": 50
                },
                "words": "伍云龙"
            },
            "性别": {
                "location": {
                    "left": 269,
                    "top": 262,
                    "width": 33,
                    "height": 52
                },
                "words": "男"
            },
            "民族": {
                "location": {
                    "left": 492,
                    "top": 279,
                    "width": 30,
                    "height": 37
                },
                "words": "汉"
            }
        },
        "words_result_num": 6
    }

    AES加密

    您可以选择使用AES加密来请求本身份证识别接口,支持对身份证图片及识别结果进行加密后传输,示意图如下:

    image.png

    1. 在百度云控制台「文字识别-应用列表-管理」中获取您的AES Key
    2. 使用AES Key对将要识别的图片进行加密
    3. 将加密后的图片传入接口,请求参数AESEncry设置为true
    4. 接口返回加密后的识别结果,使用AES Key进行解密,得到明文识别结果

    使用AES加密不影响身份证识别接口支持的质量检测、风险检测等其他能力,也不影响识别效果。

    请求说明

    请求示例

    HTTP 方法:POST

    请求URL: https://aip.baidubce.com/rest/2.0/ocr/v1/idcard

    URL参数:

    参数
    access_token 通过API Key和Secret Key获取的access_token,参考“Access Token获取

    Header如下:

    参数
    Content-Type application/x-www-form-urlencoded

    Body中放置请求参数,参数详情如下:

    请求参数

    参数 是否必选 类型 可选值范围 说明
    image string - AES加密后的图像数据,请对加密图片进行base64编码,要求base64编码后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/jpeg/png/bmp格式
    AESEncry string true/false 使用AES加密请传true
    id_card_side string front/back -front:身份证含照片的一面
    -back:身份证带国徽的一面
    自动检测身份证正反面,如果传参指定方向与图片相反,支持正常识别,返回参数image_status字段为"reversed_side"
    detect_direction string - 此参数新版本无需传,支持自动检测图像旋转角度
    detect_risk string true/false 是否开启身份证风险类型(身份证复印件、临时身份证、身份证翻拍、修改过的身份证)功能,默认不开启,即:false。
    - true:开启,请查看返回参数risk_type;
    - false:不开启
    detect_photo string true/false 是否检测头像内容,默认不检测。可选值:true-检测头像并返回头像的 base64 编码及位置信息

    请求代码示例

    提示一:使用示例代码前,请记得替换其中的示例Token、图片地址或Base64信息。

    提示二:部分语言依赖的类或库,请在代码注释中查看下载地址。

    # -*- coding: utf-8 -*-
    #
    from urllib import urlencode
    import base64
    from urllib import unquote
    import requests
    import json
    from Crypto.Cipher import AES
    import binascii
    from Crypto.Cipher import AES
    import base64
    
    ak = "ak"
    # 文字识别应用的API Key
    sk = "sk"
    # 文字识别应用的Secret Key
    
    aes = 'res'
    # aes key 从控制台 文字识别-应用列表-应用管理 获取
    
    class AESCipher:
        def __init__(self, key):
            self.key = self.get_key(key)
    
        def get_key(self, key):
            st = bytearray()
            for s in key:
                st.append(int(s, 16))
            str = st.decode('utf-8')
            return str
    
        def pad(self, text):
            # 填充方法,加密内容必须为16字节的倍数
            text_length = len(text)
            amount_to_pad = AES.block_size - (text_length % AES.block_size)
            if amount_to_pad == 0:
                amount_to_pad = AES.block_size
            pad = chr(amount_to_pad)
            return text + pad * amount_to_pad
    
        def __unpad(self, text):
            # 截取填充的字符
            pad = ord(text[-1])
            return text[:-pad]
    
            # 加密函数
    
        def encrypt(self, raw):
            raw = self.pad(raw)
            cipher = AES.new(self.key, AES.MODE_ECB)
            return base64.b64encode(cipher.encrypt(raw))
    
        def decrypt(self, enc):
            """
            解密方法
            :param enc: base64编码的密文 str
            :return: 解密后的明文 str
            """
            cipher = AES.new(self.key, AES.MODE_ECB)
            return self.__unpad(cipher.decrypt(enc))
    
    
    def get_accessToken():
        url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={ak}&client_secret={sk}".format(
            ak=ak, sk=sk)
        response = requests.get(url)
        return response.json()['access_token']
    
    
    encryptor = AESCipher(aes)
    
    token = get_accessToken()
    # 改成接口文档里的url
    nameurl = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard"
    url = nameurl + "?access_token={token}".format(token=token)
    print url
    
    f = open('resources/my.jpg', 'rb')
    d = f.read()
    r_data = encryptor.encrypt(d)
    # 构造请求数据格式
    data = {}
    data['image'] = r_data
    data['id_card_side'] = 'front'
    data['AESEncry'] = 'true'
    headers = {'content-type': 'application/x-www-form-urlencoded'}
    
    res = requests.post(url=url, data=data, headers=headers)
    #res= json.dumps(res.content, ensure_ascii=False)
    data=json.loads(res.content)
    result=encryptor.decrypt(base64.b64decode(data['result']))
    print result
    package AES;
    
    import com.alibaba.fastjson.JSONObject;
    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;
    import java.net.URLEncoder;
    import java.util.Base64;
    
    public class Idcard {
    
        /**
         * 重要提示代码中所需工具类
         * FileUtil,HttpUtil请从
         * https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
         * https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
         * 下载
         */
    
        // 请求url
        static String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
    
        // aes key 从console控制台获取
        static String aesKey = "[16位 aeskey]";
    
        static byte[] originAesKey = null;
    
        public static String idcard() {
            try {
                // 本地文件路径
                String filePath = "[本地文件路径]";
                byte[] imgData = FileUtil.readFileByBytes(filePath);
    
                String imgStr = encryptImg(aesKey, imgData);
    
                String imgParam = URLEncoder.encode(imgStr, "UTF-8");
    
                String param = "id_card_side=" + "front" +
                        "&image=" + imgParam +
                        "&AESEncry=" + true ;
    
                String accessToken = "[access token]";
    
                String encryptResult = HttpUtil.post(url, accessToken, param);
    
                String decryptResult = parseResult(encryptResult);
    
                return decryptResult;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 加密图片
         *
         * @param aesKey
         * @param imgData
         * @return
         * @throws Exception
         */
        private static String encryptImg(String aesKey, byte[] imgData) throws Exception {
            originAesKey = AesKeyUtil.parseAesKey(aesKey);
            byte[] encImgBytes = AesUtil.encrypt(imgData, originAesKey);
            String imgStr = Base64Util.encodeBase64(encImgBytes);
            return imgStr;
        }
    
        /**
         * 解密结果
         *
         * @param encryptResult
         * @return
         * @throws Exception
         */
        private static String parseResult(String encryptResult) throws Exception {
            JSONObject obj = JSONObject.parseObject(encryptResult);
            String result = obj.getString("result");
            byte[] arr = Base64Util.decodeBase64(result);
            String decryptResult = new String(AesUtil.decrypt(arr, originAesKey));
            return decryptResult;
        }
    
        public static void main(String[] args) {
            Idcard.idcard();
        }
    
    
        static class AesKeyUtil {
            private static final String HEX = "0123456789abcdef";
    
            /**
             * 获得原生的128位的aeskey
             * 因为一个byte位8位最后生成的byte数组长度为16
             * <p>
             * 16 * 8 = 128
             *
             * @param hex
             * @return
             */
            public static byte[] parseAesKey(String hex) throws Exception {
                char[] data = hex.toCharArray();
                if (data.length != 16) {
                    throw new Exception(" ase key illegal ");
                }
                return decode(hex.toCharArray());
            }
    
            private static byte[] decode(char[] data) throws IllegalArgumentException {
                int len = data.length;
    
                byte[] out = new byte[len];
    
                for (int i = 0; i < len; i++) {
                    int f = toDigit(data[i]);
                    out[i] = (byte) (f);
                }
                return out;
            }
    
            private static int toDigit(char ch) {
                return HEX.indexOf(ch);
            }
        }
    
        static class AesUtil {
    
            private static final String ALGORITHM = "AES";
    
            private static final String ALGORITHM_STR = "AES/ECB/PKCS5Padding";
    
            /**
             * aes 加密
             */
            private static byte[] encrypt(byte[] src, byte[] aesKey) throws Exception {
                Cipher cipher = getCipher(aesKey, Cipher.ENCRYPT_MODE);
                byte[] ret = cipher.doFinal(src);
                return ret;
            }
    
            /**
             * aes 解密
             */
            public static byte[] decrypt(byte[] src, byte[] aesKey) throws Exception {
                Cipher cipher = getCipher(aesKey, Cipher.DECRYPT_MODE);
                byte[] original = cipher.doFinal(src);
                return original;
            }
    
            private static Cipher getCipher(byte[] aesKey, int mode) throws Exception {
                SecretKeySpec secretKeySpec = new SecretKeySpec(aesKey, ALGORITHM);
                Cipher cipher = Cipher.getInstance(ALGORITHM_STR);
                cipher.init(mode, secretKeySpec);
                return cipher;
            }
        }
    
        static class Base64Util {
    
            private static Base64.Encoder ENCODER = Base64.getEncoder();
    
            // base64 加密
            private static Base64.Decoder DECODER = Base64.getDecoder();
    
            /**
             * base64加密
             *
             * @param arr
             * @return
             */
            private static String encodeBase64(byte[] arr) {
                String base64 = null;
                try {
                    base64 = ENCODER.encodeToString(arr);
                } catch (Exception e) {
                }
                return base64;
            }
    
            /**
             * base64解密
             *
             * @param str
             * @return
             */
            public static byte[] decodeBase64(String str) {
                byte[] encodeBase64 = new byte[0];
                try {
                    encodeBase64 = DECODER.decode(str);
                } catch (Exception e) {
                }
                return encodeBase64;
            }
        }
    }
    #include <iostream>
    #include <map>
    #include <curl/curl.h>
    #include <cryptopp/aes.h>
    #include <cryptopp/filters.h>
    #include "json/json.h"
    #include "aip/base/base64.h"
    #include "cryptopp/hex.h"
    #include "openssl/aes.h"
    #include <openssl/evp.h>
    #include <fstream>
    
    #define KEY_SIZE_16B            16
    #define KEY_SIZE_24B            24
    #define KEY_SIZE_32B            32
    
    using CryptoPP::HexEncoder;
    using CryptoPP::HexDecoder;
    
    using CryptoPP::StringSource;
    
    // libcurl库下载链接:https://curl.haxx.se/download.html
    // jsoncpp库下载链接:https://github.com/open-source-parsers/jsoncpp/
    //const static std::string request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
    //获取token
    inline size_t onWriteData(void *buffer, size_t size, size_t nmemb, void *userp) {
        std::string *str = dynamic_cast<std::string *>((std::string *) userp);
        str->append((char *) buffer, size * nmemb);
        return nmemb;
    }
    
    int get_token(
            std::string ak,
            std::string sk,
            std::string *token) {
        CURL *curl = curl_easy_init();
        struct curl_slist *slist = NULL;
        std::map<std::string, std::string> params;
        std::string response;
        std::string error;
        params["grant_type"] = "client_credentials";
        params["client_id"] = ak;
        params["client_secret"] = sk;
        std::string url = "https://aip.baidubce.com/oauth/2.0/token?"
                          "grant_type=client_credentials&client_id=" + ak + "&client_secret=" + sk;
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
        curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
        curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 2000);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 2000);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_easy_setopt(curl, CURLOPT_VERBOSE, false);
        int status_code = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
        curl_slist_free_all(slist);
        Json::CharReaderBuilder crbuilder;
        std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
        Json::Value obj;
        reader->parse(response.data(), response.data() + response.size(), &obj, &error);
        *token = obj["access_token"].asString();
    
        return status_code;
    }
    
    
    std::string JsonToString(const Json::Value &root) {
        static Json::Value def = []() {
            Json::Value def;
            Json::StreamWriterBuilder::setDefaults(&def);
            def["emitUTF8"] = true;
            return def;
        }();
    
        std::ostringstream stream;
        Json::StreamWriterBuilder stream_builder;
        stream_builder.settings_ = def;//Config emitUTF8
        std::unique_ptr<Json::StreamWriter> writer(stream_builder.newStreamWriter());
        writer->write(root, &stream);
        return stream.str();
    }
    
    
    int hex_char_value(char c) {
        if (c >= '0' && c <= '9')
            return c - '0';
        else if (c >= 'a' && c <= 'f')
            return (c - 'a' + 10);
        else if (c >= 'A' && c <= 'F')
            return (c - 'A' + 10);
        assert(0);
        return 0;
    }
    
    std::string get_key(std::string res) {
        std::string lvStr;
        for (int i = 0; i < 16; i++) {
            int x = hex_char_value(res[i]);
            char c = x;
            std::cout << c;
            lvStr.append(1, c);
        }
        return lvStr;
    }
    
    std::string ecb_encrypt(std::string res, std::string source) {
        int outlen = 0;
        int i = source.size() / 16;
        int tail = source.size() % 16;
        if (tail > 0) {
            i++;
        }
        unsigned char encData[16 * i];
        EVP_CIPHER_CTX *ctx;
        ctx = EVP_CIPHER_CTX_new();
        EVP_CipherInit_ex(ctx, EVP_aes_128_ecb(), NULL,
                          reinterpret_cast<const unsigned char *>(get_key(res).c_str()), NULL, 1);
        EVP_CipherUpdate(ctx, encData, &outlen, reinterpret_cast<const unsigned char *>(source.c_str()), source.size());
        EVP_CipherFinal(ctx, encData + outlen, &outlen);
        EVP_CIPHER_CTX_free(ctx);
        std::string data = aip::base64_encode(reinterpret_cast<const char *>(encData), sizeof(encData));
        return data;
    }
    
    std::string ecb_decrypt(std::string res, std::string decode) {
        std::string data = aip::base64_decode(decode);
        int decLen = 0;
        int outlen = 0;
        unsigned char decData[data.size()];
        EVP_CIPHER_CTX *ctx2;
        ctx2 = EVP_CIPHER_CTX_new();
        EVP_CipherInit_ex(ctx2, EVP_aes_128_ecb(), NULL, reinterpret_cast<const unsigned char *>(get_key(res).c_str()),
                          NULL, 0);
        EVP_CipherUpdate(ctx2, decData, &outlen, reinterpret_cast<const unsigned char *>(data.c_str()), data.size());
        decLen = outlen;
        EVP_CipherFinal(ctx2, decData + outlen, &outlen);
        decLen += outlen;
        EVP_CIPHER_CTX_free(ctx2);
        decData[decLen] = '\0';
        printf("decrypt: %s\n", decData);
        std::string result;
        result = reinterpret_cast<const char *>(decData);
        return result;
    }
    
    template<class CharT, class Traits, class Allocator>
    std::basic_istream<CharT, Traits> &getall(std::basic_istream<CharT, Traits> &input,
                                              std::basic_string<CharT, Traits, Allocator> &str) {
        std::ostringstream oss;
        oss << input.rdbuf();
        str.assign(oss.str());
        return input;
    }
    
    inline int get_file_content(const char *filename, std::string *out) {
        std::ifstream in(filename, std::ios::in | std::ios::binary);
        if (in) {
            getall(in, *out);
            return 0;
        } else {
            return -1;
        }
    }
    
    /**
     * 身份证识别
     * @return 调用成功返回0,发生错误返回其他错误码
     */
    Json::Value idcard(const std::string &access_token) {
        Json::Value obj;
        std::string url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + access_token;
        CURL *curl = NULL;
        CURLcode result_code;
        //图片内容
        std::string file_content;
        get_file_content("/Users/lidang/pyproject/baidu/aip/api-python-sdk/test/resources/my.jpg", &file_content);
    //    std::string base64 = aip::base64_encode(file_content.c_str(), (int) file_content.size());
        std::string res = "e1ad10e3d69689e0";
        std::string base64 = ecb_encrypt(res, file_content);
        int is_success;
        std::string response;
        std::string error;
        curl = curl_easy_init();
        if (curl) {
            curl_easy_setopt(curl, CURLOPT_URL, url.data());
            curl_easy_setopt(curl, CURLOPT_POST, 1);
            curl_httppost *post = NULL;
            curl_httppost *last = NULL;
            curl_formadd(&post, &last, CURLFORM_COPYNAME, "id_card_side", CURLFORM_COPYCONTENTS, "front", CURLFORM_END);
            curl_formadd(&post, &last, CURLFORM_COPYNAME, "image", CURLFORM_COPYCONTENTS, base64.c_str(), CURLFORM_END);
            curl_formadd(&post, &last, CURLFORM_COPYNAME, "AESEncry", CURLFORM_COPYCONTENTS, "true", CURLFORM_END);
            curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
            curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
            result_code = curl_easy_perform(curl);
            if (result_code != CURLE_OK) {
                fprintf(stderr, "curl_easy_perform() failed: %s\n",
                        curl_easy_strerror(result_code));
                is_success = 1;
                return is_success;
            }
            Json::CharReaderBuilder crbuilder;
            std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
            reader->parse(response.data(), response.data() + response.size(), &obj, &error);
            curl_easy_cleanup(curl);
            is_success = 0;
            return obj;
        } else {
            fprintf(stderr, "curl_easy_init() failed.");
            is_success = 1;
        }
        return obj;
    }
    
    int main() {
    
    //    aipt::test_ocr();
    //    aipt::test_kg();
    //    aipt::test_speech();
    //    aipt::test_face();
    //    aipt::test_nlp();
    //    aipt::test_ocr();
    //    aipt::test_image_censor();
    //    aipt::run_test(1);
        std::string ak = "ak";
        std::string sk = "sk";
        std::string res = "控制台的aeskey";
        std::string output;
        std::string token;
        get_token(ak, sk, &token);
        Json::Value result;
        result = idcard(token);
        std::cout << result["result"];
        std::string data = ecb_decrypt(res, result["result"].asString());
        std::cout << data + "\n";
    //    std::string encate = ecb_encrypt(res, "123456789123456789");
    //    std::cout << encate + "\n";
    //    std::string decode = ecb_decrypt(res,encate);
    //    std::cout << decode+"\n";
        return 0;
    }
    <?php
    
    function buildUrl($url, $params)
    {
        if (!empty($params)) {
            $str = http_build_query($params);
            return $url . (strpos($url, '?') === false ? '?' : '&') . $str;
        } else {
            return $url;
        }
    }
    
    function buildHeaders($headers)
    {
        $result = array();
        foreach ($headers as $k => $v) {
            $result[] = sprintf('%s:%s', $k, $v);
        }
        return $result;
    }
    
    function get($url, $params = array(), $headers = array())
    {
        $url = buildUrl($url, $params);
    
        $headers = array_merge($headers, buildHeaders($headers));
    
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        $content = curl_exec($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
        if ($code === 0) {
            throw new Exception(curl_error($ch));
        }
    
        curl_close($ch);
        return array(
            'code' => $code,
            'content' => $content,
        );
    }
    
    function post($url, $data = array(), $headers = array())
    {
        $ch = curl_init();
        var_dump($url);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($data) ? http_build_query($data) : $data);
    
        $content = curl_exec($ch);
        $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    
        if ($code === 0) {
            throw new Exception(curl_error($ch));
        }
    
        curl_close($ch);
        return array(
            'code' => $code,
            'content' => $content,
        );
    }
    
    function decrypt($sStr, $key)
    {
        $sStr = base64_decode($sStr);
        $decrypted = openssl_decrypt($sStr, 'AES-128-ECB', get_key($key), OPENSSL_RAW_DATA);
        return $decrypted;
    }
    
    function encrypt($input, $key)
    {
        $data = openssl_encrypt($input, 'AES-128-ECB', get_key($key), OPENSSL_RAW_DATA);
        $data = base64_encode($data);
        return $data;
    }
    
    function bytesToStr($bytes)
    {
        $str = '';
        foreach ($bytes as $ch) {
            $str .= chr($ch);
        }
        return $str;
    }
    
    function get_key($key)
    {
        $arr = str_split($key);
        $bytes = array();
        for ($i = 0; $i < count($arr); $i++) {
            $bytes[] = ord(chr(hexdec($arr[$i])));
        }
        return bytesToStr($bytes);
    }
    
    $ak = "ak";
    $sk = "sk";
    #aes key 从控制台 文字识别-应用列表-应用管理 获取
    $aes = 'res';
    $response = get('https://aip.baidubce.com/oauth/2.0/token', array(
        'grant_type' => 'client_credentials',
        'client_id' => $ak,
        'client_secret' => $sk,
    ));
    $obj = json_decode($response['content'], true);
    
    $token = $obj['access_token'];
    $url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=' . $token;
    $img = file_get_contents('idcard.jpg');
    $img_data = encrypt($img, $aes);
    
    $data = array();
    $data['image'] = $img_data;
    $data['id_card_side'] = 'front';
    $data['AESEncry'] = 'true';
    
    $response = post($url, $data, array());
    $result =$response['content'];
    $book = json_decode($result,true);
    $res=decrypt($book["result"],$aes);
    echo $res;
    //构造请求数据json_decode($ content, true);
    using System;
    using NUnit.Framework;
    using System.Text;
    using System.Security.Cryptography;
    using System.IO;
    using System.Net;
    using System.Collections.Generic;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System.Linq;
    namespace Baidu.Aip
    {
        [TestFixture]
        public class Demo
        {
         
    
            public static byte[] getFileByte(String fileName)
            {
                FileStream filestream = new FileStream(fileName, FileMode.Open);
                byte[] arr = new byte[filestream.Length];
                filestream.Read(arr, 0, (int)filestream.Length);
                filestream.Close();
                return arr;
            }
             public static string ParseQueryString(Dictionary<string, string> querys)
            {
                if (querys.Count == 0)
                    return "";
                return querys
                    .Select(pair => pair.Key + "=" + pair.Value)
                    .Aggregate((a, b) => a + "&" + b);
            }
            public static string StreamToString(Stream ss, Encoding enc)
            {
                string ret;
                using (var reader = new StreamReader(ss, enc))
                {
                    ret = reader.ReadToEnd();
                }
                ss.Close();
                return ret;
            }
            public static JObject OpenApiFetchToken(string ak, string sk, bool throws = false, bool debugLog = false)
            {
                var querys = new Dictionary<string, string>
                {
                    {"grant_type", "client_credentials"},
                    {"client_id", ak},
                    {"client_secret", sk}
                };
                var url = string.Format("{0}?{1}", "https://aip.baidubce.com/oauth/2.0/token", ParseQueryString(querys));
                if (debugLog)
                    Console.WriteLine(url);
                var webReq = (HttpWebRequest)WebRequest.Create(url);
                try
                {
                    var resp = (HttpWebResponse)webReq.GetResponse();
                    if (resp.StatusCode == HttpStatusCode.OK)
                    {
                        var respStr = StreamToString(resp.GetResponseStream(), Encoding.UTF8);
                        var obj = JsonConvert.DeserializeObject(respStr) as JObject;
                        if (obj["access_token"] != null && obj["expires_in"] != null)
                            return obj;
                        if (throws)
                            throw new AipException("Failed to request token. " + (string)obj["error_description"]);
                        return null;
                    }
                    if (throws)
                        throw new AipException("Failed to request token. " + resp.StatusCode + resp.StatusDescription);
                }
                catch (Exception e)
                {
                    if (throws)
                        throw new AipException("Failed to request token. " + e.Message);
                    return null;
                }
    
                return null;
            }
            public static string UrlEncode(string str)
            {
                StringBuilder sb = new StringBuilder();
                byte[] byStr = System.Text.Encoding.UTF8.GetBytes(str); //默认是System.Text.Encoding.Default.GetBytes(str)
                for (int i = 0; i < byStr.Length; i++)
                {
                    sb.Append(@"%" + Convert.ToString(byStr[i], 16));
                }
    
                return (sb.ToString());
            }
            public static string Encrypt(string toEncrypt, string key)
            {
                byte[] keyArray = GetKey(key);
                byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
                Console.WriteLine("Hello World!" + keyArray.Length);
                RijndaelManaged rDel = new RijndaelManaged();
                rDel.Key = keyArray;
                rDel.Mode = CipherMode.ECB;
                rDel.Padding = PaddingMode.PKCS7;
    
                ICryptoTransform cTransform = rDel.CreateEncryptor();
                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
    
                return Convert.ToBase64String(resultArray, 0, resultArray.Length);
            }
            public static string Encrypt(byte[] toEncryptArray, string key)
            {
                byte[] keyArray = GetKey(key);
                Console.WriteLine("Hello World!" + keyArray.Length);
                RijndaelManaged rDel = new RijndaelManaged();
                rDel.Key = keyArray;
                rDel.Mode = CipherMode.ECB;
                rDel.Padding = PaddingMode.PKCS7;
    
                ICryptoTransform cTransform = rDel.CreateEncryptor();
                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
    
                return Convert.ToBase64String(resultArray, 0, resultArray.Length);
            }
            public static  byte[] GetKey(string key)
            {
                byte[] result = new byte[key.Length];
                char[] array = key.ToArray();
                int i = 0;
                for (int a = 0; a < array.Length; a = a + 1)
                {
                    string ch =array[a]+"";
                    int val=Convert.ToInt32(ch,16);
                    result[a] = (byte)val;
                }
                return result;
            }
        
    
    
            /*
             * AES解密
             * */
            public static string Decrypt(string toDecrypt, string key)
            {
                byte[] keyArray = GetKey(key);
                byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
    
                RijndaelManaged rDel = new RijndaelManaged();
                rDel.Key = keyArray;
                rDel.Mode = CipherMode.ECB;
                rDel.Padding = PaddingMode.PKCS7;
    
                ICryptoTransform cTransform = rDel.CreateDecryptor();
                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
    
                return UTF8Encoding.UTF8.GetString(resultArray);
            }
    
            [Test]
            public void demo()
              {
                string res = "控制台的aeskey";
                string ak = "ak";
                string sk = "sk";
    
                string host = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + OpenApiFetchToken(ak, sk)["access_token"];
                //Console.WriteLine("url:"+host);
                Encoding encoding = Encoding.Default;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host);
                request.Method = "post";
                request.KeepAlive = true;
                //// 图片的base64编码
                byte[] file = getFileByte("图片路径");
                string base64= Encrypt(file, res);
                string str = "AESEncry=true&id_card_side=" + "front" + "&image=" + UrlEncode(base64);
                byte[] buffer = encoding.GetBytes(str);
                request.ContentLength = buffer.Length;
                request.GetRequestStream().Write(buffer, 0, buffer.Length);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
                string result = reader.ReadToEnd();
                Console.WriteLine("身份证识别:");
                Console.WriteLine(result);
                Console.WriteLine("解密");
                var obj = JsonConvert.DeserializeObject(result) as JObject;
                var content=Decrypt((string)obj["result"], res);
                Console.WriteLine(content);
            }
    }
    }

    返回说明

    返回示例

    {
        "log_id":"2648325511",
        "result":"密文"
    }

    请对result密文进行base64解码后得到byte流,再进行AES解密,得到识别结果的明文。

    上一篇
    通用场景文字识别
    下一篇
    身份证混贴识别