身份证识别
接口描述
支持对二代居民身份证正反面所有8个字段进行结构化识别,包括姓名、性别、民族、出生日期、住址、身份证号、签发机关、有效期限,识别准确率超过99%;同时支持身份证正面头像检测,并返回头像切片的base64编码及位置信息。
同时,支持对用户上传的身份证图片进行图像质量和风险检测,是否存在正反颠倒、模糊、欠曝、过曝等质量问题,可识别图片是否为复印件或临时身份证,是否被翻拍或编辑,是否存在四角不完整、头像或关键字段被遮挡。
增值能力 | 详情 |
---|---|
裁剪能力 | 头像检测与切片:返回头像切片的base64编码及位置信息 |
身份证检测与切片:返回身份证的base64编码及位置信息(去掉证件外围多余背景、自动矫正拍摄角度) | |
质量检测 | 身份证图片模糊检测 |
身份证关键字段反光或过曝光 | |
身份证图片较暗或欠曝光 | |
身份证边框/四角不完整告警 | |
身份证头像或关键字段被遮挡/马赛克告警 | |
风险检测 | 身份证复印件告警 |
临时身份证告警 | |
身份证翻拍告警 | |
身份证PS编辑告警 | |
身份证证号不合法告警 | |
身份证证号和出生日期、性别信息不一致告警 |
视频教程请参见 身份证识别API调用教程(视频版)
在线调试
您可以在 示例代码中心 中调试该接口,可进行签名验证、查看在线调用的请求内容和返回结果、示例代码的自动生成。
请求说明
请求示例
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,需去掉编码头(data:image/jpeg;base64, ) 要求base64编码和urlencode后大小不超过8M,最短边至少15px,最长边最大8192px,支持jpg/jpeg/png/bmp格式 |
url | 和image二选一 | string | - | 图片完整URL,URL长度不超过1024字节,URL对应的图片base64编码后大小不超过8M,最短边至少15px,最长边最大8192px,支持jpg/jpeg/png/bmp格式,当image字段存在时url字段失效请注意关闭URL防盗链 |
id_card_side | 是 | string | front/back | -front:身份证含照片的一面-back:身份证带国徽的一面自动检测身份证正反面,如果传参指定方向与图片相反,支持正常识别,返回参数image_status字段为"reversed_side" |
detect_ps | 否 | string | true/false | 是否检测上传的身份证被PS,默认不检测。可选值:-true:检测 - false:不检测 |
detect_risk | 否 | string | true/false | 是否开启身份证风险类型(身份证复印件、临时身份证、身份证翻拍、修改过的身份证)检测功能,默认不开启,即:false。- true:开启,请查看返回参数risk_type;- false:不开启 |
detect_quality | 否 | string | true/false | 是否开启身份证质量类型(清晰模糊、边框/四角不完整、头像或关键字段被遮挡/马赛克)检测功能,默认不开启,即:false。- true:开启,请查看返回参数card_quality;- false:不开启 |
detect_photo | 否 | string | true/false | 是否检测头像内容,默认不检测。可选值:true-检测头像并返回头像的 base64 编码及位置信息 |
detect_card | 否 | string | true/false | 是否检测身份证进行裁剪,默认不检测。可选值:true-检测身份证并返回证照的 base64 编码及位置信息 |
detect_direction | 否 | string | true/false | 是否检测上传的身份证图片方向,默认不检测。可选值:-true:检测 - false:不检测 |
请求代码示例
提示一:使用示例代码前,请记得替换其中的示例Token、图片地址或Base64信息。
提示二:部分语言依赖的类或库,请在代码注释中查看下载地址。
1curl -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'
1# encoding:utf-8
2
3import requests
4import base64
5
6'''
7身份证识别
8'''
9
10request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard"
11# 二进制方式打开图片文件
12f = open('[本地文件]', 'rb')
13img = base64.b64encode(f.read())
14
15params = {"id_card_side":"front","image":img}
16access_token = '[调用鉴权接口获取的token]'
17request_url = request_url + "?access_token=" + access_token
18headers = {'content-type': 'application/x-www-form-urlencoded'}
19response = requests.post(request_url, data=params, headers=headers)
20if response:
21 print (response.json())
1package com.baidu.ai.aip;
2
3import com.baidu.ai.aip.utils.Base64Util;
4import com.baidu.ai.aip.utils.FileUtil;
5import com.baidu.ai.aip.utils.HttpUtil;
6
7import java.net.URLEncoder;
8
9/**
10* 身份证识别
11*/
12public class Idcard {
13
14 /**
15 * 重要提示代码中所需工具类
16 * FileUtil,Base64Util,HttpUtil,GsonUtils请从
17 * https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
18 * https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
19 * https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
20 * https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
21 * 下载
22 */
23 public static String idcard() {
24 // 请求url
25 String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
26 try {
27 // 本地文件路径
28 String filePath = "[本地文件路径]";
29 byte[] imgData = FileUtil.readFileByBytes(filePath);
30 String imgStr = Base64Util.encode(imgData);
31 String imgParam = URLEncoder.encode(imgStr, "UTF-8");
32
33 String param = "id_card_side=" + "front" + "&image=" + imgParam;
34
35 // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
36 String accessToken = "[调用鉴权接口获取的token]";
37
38 String result = HttpUtil.post(url, accessToken, param);
39 System.out.println(result);
40 return result;
41 } catch (Exception e) {
42 e.printStackTrace();
43 }
44 return null;
45 }
46
47 public static void main(String[] args) {
48 Idcard.idcard();
49 }
50}
1#include <iostream>
2#include <curl/curl.h>
3
4// libcurl库下载链接:https://curl.haxx.se/download.html
5// jsoncpp库下载链接:https://github.com/open-source-parsers/jsoncpp/
6const static std::string request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
7static std::string idcard_result;
8/**
9 * curl发送http请求调用的回调函数,回调函数中对返回的json格式的body进行了解析,解析结果储存在全局的静态变量当中
10 * @param 参数定义见libcurl文档
11 * @return 返回值定义见libcurl文档
12 */
13static size_t callback(void *ptr, size_t size, size_t nmemb, void *stream) {
14 // 获取到的body存放在ptr中,先将其转换为string格式
15 idcard_result = std::string((char *) ptr, size * nmemb);
16 return size * nmemb;
17}
18/**
19 * 身份证识别
20 * @return 调用成功返回0,发生错误返回其他错误码
21 */
22int idcard(std::string &json_result, const std::string &access_token) {
23 std::string url = request_url + "?access_token=" + access_token;
24 CURL *curl = NULL;
25 CURLcode result_code;
26 int is_success;
27 curl = curl_easy_init();
28 if (curl) {
29 curl_easy_setopt(curl, CURLOPT_URL, url.data());
30 curl_easy_setopt(curl, CURLOPT_POST, 1);
31 curl_httppost *post = NULL;
32 curl_httppost *last = NULL;
33 curl_formadd(&post, &last, CURLFORM_COPYNAME, "id_card_side", CURLFORM_COPYCONTENTS, "front", CURLFORM_END);
34 curl_formadd(&post, &last, CURLFORM_COPYNAME, "image", CURLFORM_COPYCONTENTS, "【base64_img】", CURLFORM_END);
35
36 curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
37 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
38 result_code = curl_easy_perform(curl);
39 if (result_code != CURLE_OK) {
40 fprintf(stderr, "curl_easy_perform() failed: %s\n",
41 curl_easy_strerror(result_code));
42 is_success = 1;
43 return is_success;
44 }
45 json_result = idcard_result;
46 curl_easy_cleanup(curl);
47 is_success = 0;
48 } else {
49 fprintf(stderr, "curl_easy_init() failed.");
50 is_success = 1;
51 }
52 return is_success;
53}
1<?php
2/**
3 * 发起http post请求(REST API), 并获取REST请求的结果
4 * @param string $url
5 * @param string $param
6 * @return - http response body if succeeds, else false.
7 */
8function request_post($url = '', $param = '')
9{
10 if (empty($url) || empty($param)) {
11 return false;
12 }
13
14 $postUrl = $url;
15 $curlPost = $param;
16 // 初始化curl
17 $curl = curl_init();
18 curl_setopt($curl, CURLOPT_URL, $postUrl);
19 curl_setopt($curl, CURLOPT_HEADER, 0);
20 // 要求结果为字符串且输出到屏幕上
21 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
22 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
23 // post提交方式
24 curl_setopt($curl, CURLOPT_POST, 1);
25 curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
26 // 运行curl
27 $data = curl_exec($curl);
28 curl_close($curl);
29
30 return $data;
31}
32
33$token = '[调用鉴权接口获取的token]';
34$url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=' . $token;
35$img = file_get_contents('[本地文件路径]');
36$img = base64_encode($img);
37$bodys = array(
38 'id_card_side' => "front",
39 'image' => $img
40);
41$res = request_post($url, $bodys);
42
43var_dump($res);
1using System;
2using System.IO;
3using System.Net;
4using System.Text;
5using System.Web;
6
7namespace com.baidu.ai
8{
9 public class Idcard
10 {
11 // 身份证识别
12 public static string idcard()
13 {
14 string token = "[调用鉴权接口获取的token]";
15 string host = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + token;
16 Encoding encoding = Encoding.Default;
17 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host);
18 request.Method = "post";
19 request.KeepAlive = true;
20 // 图片的base64编码
21 string base64 = getFileBase64("[本地图片文件]");
22 String str = "id_card_side=" + "front" + "&image=" + HttpUtility.UrlEncode(base64);
23 byte[] buffer = encoding.GetBytes(str);
24 request.ContentLength = buffer.Length;
25 request.GetRequestStream().Write(buffer, 0, buffer.Length);
26 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
27 StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
28 string result = reader.ReadToEnd();
29 Console.WriteLine("身份证识别:");
30 Console.WriteLine(result);
31 return result;
32 }
33
34 public static String getFileBase64(String fileName) {
35 FileStream filestream = new FileStream(fileName, FileMode.Open);
36 byte[] arr = new byte[filestream.Length];
37 filestream.Read(arr, 0, (int)filestream.Length);
38 string baser64 = Convert.ToBase64String(arr);
39 filestream.Close();
40 return baser64;
41 }
42 }
43}
返回说明
返回参数
字段 | 是否必选 | 类型 | 说明 |
---|---|---|---|
log_id | 是 | uint64 | 唯一的log id,用于问题定位 |
words_result | 是 | array[] | 定位和识别结果数组 |
words_result_num | 是 | uint32 | 识别结果数,表示words_result的元素个数 |
direction | 否 | int32 | 图像方向,输入参数 detect_direction= true 时返回。 - - 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-未知状态 |
card_ps | 否 | string | 输入参数 detect_ps = true 时,则返回该字段,判断身份证是否被PS,返回值: - 0:正常, - 1:PS, - -1:无效 |
risk_type | 否 | string | 输入参数 detect_risk = true 时,则返回该字段识别身份证风险类型: normal-正常身份证; copy-复印件; temporary-临时身份证; screen-翻拍; unknown-其他未知情况 |
edit_tool | 否 | string | 如果参数 detect_risk = true 时,则返回此字段。如果检测身份证被编辑过,该字段指定编辑软件名称,如:Adobe Photoshop CC 2014 (Macintosh),如果没有被编辑过则返回值无此参数 |
card_quality | 否 | object | 输入参数 detect_quality = true 时,则返回该字段识别身份证质量类型 |
+ IsClear | 否 | float | 质量类型,是否清晰,返回值包括: - 1:清晰 - 0:不清晰 |
+ IsClear_propobility | 否 | float | “是否清晰”质量类型对应的概率,值在0-1之间,值越大表示图像质量越好。默认阈值(仅为推荐值,建议按照实际业务场景,基于图片返回的具体概率值,自定义设置判断阈值):当 IsClear_propobility 超过0.5时,对应 IsClear 返回1,低于0.5,则返回0 |
+ IsComplete | 否 | float | 质量类型,是否边框/四角完整,返回值包括: - 1:边框/四角完整 - 0:边框/四角不完整 |
+ IsComplete_propobility | 否 | float | “是否边框/四角完整”质量类型对应的概率,值在0-1之间,值越大表示图像质量越好。默认阈值(仅为推荐值,建议按照实际业务场景,基于图片返回的具体概率值,自定义设置判断阈值):当 IsComplete_propobility 超过0.5时,对应 IsComplete 返回1,低于0.5,则返回0 |
+ IsNoCover | 否 | float | 质量类型,是否头像、关键字段无遮挡/马赛克,返回值包括: - 1:头像、关键字段无遮挡/马赛克 - 0:头像、关键字段有遮挡/马赛克 |
+ IsNoCover_propobility | 否 | float | “是否头像、关键字段无遮挡/马赛克”质量类型对应的概率,值在0-1之间,值越大表示图像质量越好。默认阈值(仅为推荐值,建议按照实际业务场景,基于图片返回的具体概率值,自定义设置判断阈值):当 IsNoCover_propobility 超过0.3时,对应IsNoCover 返回1,低于0.3,则返回0 |
photo | 否 | string | 当请求参数 detect_photo = true时返回,头像切图的 base64 编码(无编码头,需自行处理) |
photo_location | 否 | object | 当请求参数 detect_photo = true时返回,头像的位置信息(坐标0点为左上角) |
card_image | 否 | string | 当请求参数 detect_card = true时返回,身份证裁剪切图的 base64 编码(无编码头,需自行处理) |
card_location | 否 | object | 当请求参数 detect_card = true时返回,身份证裁剪切图的位置信息(坐标0点为左上角) |
idcard_number_type | 是 | int | 用于校验身份证号码、性别、出生是否一致,输出结果及其对应关系如下: - 1: 身份证正面所有字段全为空 0: 身份证证号不合法,此情况下不返回身份证证号 1: 身份证证号和性别、出生信息一致 2: 身份证证号和性别、出生信息都不一致 3: 身份证证号和出生信息不一致 4: 身份证证号和性别信息不一致 |
+ location | 是 | array[] | 位置数组(坐标0点为左上角) |
++ left | 是 | uint32 | 表示定位位置的长方形左上顶点的水平坐标 |
++ top | 是 | uint32 | 表示定位位置的长方形左上顶点的垂直坐标 |
++ width | 是 | uint32 | 表示定位位置的长方形的宽度 |
++ height | 是 | uint32 | 表示定位位置的长方形的高度 |
+ words | 否 | string | 识别结果字符串 |
返回示例(身份证头像面)
1{
2 "log_id": "1559208562721579319",
3 "direction": 0,
4 "image_status": "normal",
5 "photo": "/9j/4AAQSkZJRgABA......",
6 "photo_location": {
7 "width": 1189,
8 "top": 638,
9 "left": 2248,
10 "height": 1483
11 },
12 "card_image": "/9j/4AAQSkZJRgABA......",
13 "card_location": {
14 "top": 328,
15 "left": 275,
16 "width": 1329,
17 "height": 571
18 },
19 "words_result": {
20 "住址": {
21 "location": {
22 "left": 267,
23 "top": 453,
24 "width": 459,
25 "height": 99
26 },
27 "words": "南京市江宁区弘景大道3889号"
28 },
29 "公民身份号码": {
30 "location": {
31 "left": 443,
32 "top": 681,
33 "width": 589,
34 "height": 45
35 },
36 "words": "330881199904173914"
37 },
38 "出生": {
39 "location": {
40 "left": 270,
41 "top": 355,
42 "width": 357,
43 "height": 45
44 },
45 "words": "19990417"
46 },
47 "姓名": {
48 "location": {
49 "left": 267,
50 "top": 176,
51 "width": 152,
52 "height": 50
53 },
54 "words": "伍云龙"
55 },
56 "性别": {
57 "location": {
58 "left": 269,
59 "top": 262,
60 "width": 33,
61 "height": 52
62 },
63 "words": "男"
64 },
65 "民族": {
66 "location": {
67 "left": 492,
68 "top": 279,
69 "width": 30,
70 "height": 37
71 },
72 "words": "汉"
73 }
74 },
75 "words_result_num": 6
76}
返回示例(身份证国徽面)
1{
2 "words_result": {
3 "失效日期": {
4 "words": "20390711",
5 "location": {
6 "top": 445,
7 "left": 523,
8 "width": 153,
9 "height": 38
10 }
11 },
12 "签发机关": {
13 "words": "陆丰市公安局",
14 "location": {
15 "top": 377,
16 "left": 339,
17 "width": 195,
18 "height": 38
19 }
20 },
21 "签发日期": {
22 "words": "20190606",
23 "location": {
24 "top": 445,
25 "left": 343,
26 "width": 152,
27 "height": 38
28 }
29 }
30 },
31 "log_id": "1559208562721579328",
32 "words_result_num": 3,
33 "error_code": 0,
34 "image_status": "normal"
35}
AES加密
您可以选择使用AES加密来请求本身份证识别接口,支持对身份证图片及识别结果进行加密后传输,示意图如下:
- 在百度云控制台「文字识别-应用列表-管理」中获取您的AES Key
- 使用AES Key对将要识别的图片进行加密
- 将加密后的图片传入接口,请求参数AESEncry设置为true
- 接口返回加密后的识别结果,使用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编码后进行urlencode,要求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信息。
提示二:部分语言依赖的类或库,请在代码注释中查看下载地址。
1# -*- coding: utf-8 -*-
2#
3from urllib import urlencode
4import base64
5from urllib import unquote
6import requests
7import json
8from Crypto.Cipher import AES
9import binascii
10
11ak = "ak"
12# 文字识别应用的API Key
13sk = "sk"
14# 文字识别应用的Secret Key
15
16aes = 'res'
17# aes key 从控制台 文字识别-应用列表-应用管理 获取
18
19class AESCipher:
20 def __init__(self, key):
21 self.key = self.get_key(key)
22
23 def get_key(self, key):
24 st = bytearray()
25 for s in key:
26 st.append(int(s, 16))
27 str = st.decode('utf-8')
28 return str
29
30 def pad(self, text):
31 # 填充方法,加密内容必须为16字节的倍数
32 text_length = len(text)
33 amount_to_pad = AES.block_size - (text_length % AES.block_size)
34 if amount_to_pad == 0:
35 amount_to_pad = AES.block_size
36 pad = chr(amount_to_pad)
37 return text + pad * amount_to_pad
38
39 def __unpad(self, text):
40 # 截取填充的字符
41 pad = ord(text[-1])
42 return text[:-pad]
43
44 # 加密函数
45
46 def encrypt(self, raw):
47 raw = self.pad(raw)
48 cipher = AES.new(self.key, AES.MODE_ECB)
49 return base64.b64encode(cipher.encrypt(raw))
50
51 def decrypt(self, enc):
52 """
53 解密方法
54 :param enc: base64编码的密文 str
55 :return: 解密后的明文 str
56 """
57 cipher = AES.new(self.key, AES.MODE_ECB)
58 return self.__unpad(cipher.decrypt(enc))
59
60
61def get_accessToken():
62 url = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={ak}&client_secret={sk}".format(
63 ak=ak, sk=sk)
64 response = requests.get(url)
65 return response.json()['access_token']
66
67
68encryptor = AESCipher(aes)
69
70token = get_accessToken()
71# 改成接口文档里的url
72nameurl = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard"
73url = nameurl + "?access_token={token}".format(token=token)
74print url
75
76f = open('resources/my.jpg', 'rb')
77d = f.read()
78r_data = encryptor.encrypt(d)
79# 构造请求数据格式
80data = {}
81data['image'] = r_data
82data['id_card_side'] = 'front'
83data['AESEncry'] = 'true'
84headers = {'content-type': 'application/x-www-form-urlencoded'}
85
86res = requests.post(url=url, data=data, headers=headers)
87#res= json.dumps(res.content, ensure_ascii=False)
88data=json.loads(res.content)
89result=encryptor.decrypt(base64.b64decode(data['result']))
90print result
1package AES;
2
3import com.alibaba.fastjson.JSONObject;
4import javax.crypto.Cipher;
5import javax.crypto.spec.SecretKeySpec;
6import java.net.URLEncoder;
7import java.util.Base64;
8
9public class Idcard {
10
11 /**
12 * 重要提示代码中所需工具类
13 * FileUtil,HttpUtil请从
14 * https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
15 * https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
16 * 下载
17 */
18
19 // 请求url
20 static String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
21
22 // aes key 从console控制台获取
23 static String aesKey = "[16位 aeskey]";
24
25 static byte[] originAesKey = null;
26
27 public static String idcard() {
28 try {
29 // 本地文件路径
30 String filePath = "[本地文件路径]";
31 byte[] imgData = FileUtil.readFileByBytes(filePath);
32
33 String imgStr = encryptImg(aesKey, imgData);
34
35 String imgParam = URLEncoder.encode(imgStr, "UTF-8");
36
37 String param = "id_card_side=" + "front" +
38 "&image=" + imgParam +
39 "&AESEncry=" + true ;
40
41 String accessToken = "[access token]";
42
43 String encryptResult = HttpUtil.post(url, accessToken, param);
44
45 String decryptResult = parseResult(encryptResult);
46
47 return decryptResult;
48 } catch (Exception e) {
49 e.printStackTrace();
50 }
51 return null;
52 }
53
54 /**
55 * 加密图片
56 *
57 * @param aesKey
58 * @param imgData
59 * @return
60 * @throws Exception
61 */
62 private static String encryptImg(String aesKey, byte[] imgData) throws Exception {
63 originAesKey = AesKeyUtil.parseAesKey(aesKey);
64 byte[] encImgBytes = AesUtil.encrypt(imgData, originAesKey);
65 String imgStr = Base64Util.encodeBase64(encImgBytes);
66 return imgStr;
67 }
68
69 /**
70 * 解密结果
71 *
72 * @param encryptResult
73 * @return
74 * @throws Exception
75 */
76 private static String parseResult(String encryptResult) throws Exception {
77 JSONObject obj = JSONObject.parseObject(encryptResult);
78 String result = obj.getString("result");
79 byte[] arr = Base64Util.decodeBase64(result);
80 String decryptResult = new String(AesUtil.decrypt(arr, originAesKey));
81 return decryptResult;
82 }
83
84 public static void main(String[] args) {
85 Idcard.idcard();
86 }
87
88
89 static class AesKeyUtil {
90 private static final String HEX = "0123456789abcdef";
91
92 /**
93 * 获得原生的128位的aeskey
94 * 因为一个byte位8位最后生成的byte数组长度为16
95 * <p>
96 * 16 * 8 = 128
97 *
98 * @param hex
99 * @return
100 */
101 public static byte[] parseAesKey(String hex) throws Exception {
102 char[] data = hex.toCharArray();
103 if (data.length != 16) {
104 throw new Exception(" ase key illegal ");
105 }
106 return decode(hex.toCharArray());
107 }
108
109 private static byte[] decode(char[] data) throws IllegalArgumentException {
110 int len = data.length;
111
112 byte[] out = new byte[len];
113
114 for (int i = 0; i < len; i++) {
115 int f = toDigit(data[i]);
116 out[i] = (byte) (f);
117 }
118 return out;
119 }
120
121 private static int toDigit(char ch) {
122 return HEX.indexOf(ch);
123 }
124 }
125
126 static class AesUtil {
127
128 private static final String ALGORITHM = "AES";
129
130 private static final String ALGORITHM_STR = "AES/ECB/PKCS5Padding";
131
132 /**
133 * aes 加密
134 */
135 private static byte[] encrypt(byte[] src, byte[] aesKey) throws Exception {
136 Cipher cipher = getCipher(aesKey, Cipher.ENCRYPT_MODE);
137 byte[] ret = cipher.doFinal(src);
138 return ret;
139 }
140
141 /**
142 * aes 解密
143 */
144 public static byte[] decrypt(byte[] src, byte[] aesKey) throws Exception {
145 Cipher cipher = getCipher(aesKey, Cipher.DECRYPT_MODE);
146 byte[] original = cipher.doFinal(src);
147 return original;
148 }
149
150 private static Cipher getCipher(byte[] aesKey, int mode) throws Exception {
151 SecretKeySpec secretKeySpec = new SecretKeySpec(aesKey, ALGORITHM);
152 Cipher cipher = Cipher.getInstance(ALGORITHM_STR);
153 cipher.init(mode, secretKeySpec);
154 return cipher;
155 }
156 }
157
158 static class Base64Util {
159
160 private static Base64.Encoder ENCODER = Base64.getEncoder();
161
162 // base64 加密
163 private static Base64.Decoder DECODER = Base64.getDecoder();
164
165 /**
166 * base64加密
167 *
168 * @param arr
169 * @return
170 */
171 private static String encodeBase64(byte[] arr) {
172 String base64 = null;
173 try {
174 base64 = ENCODER.encodeToString(arr);
175 } catch (Exception e) {
176 }
177 return base64;
178 }
179
180 /**
181 * base64解密
182 *
183 * @param str
184 * @return
185 */
186 public static byte[] decodeBase64(String str) {
187 byte[] encodeBase64 = new byte[0];
188 try {
189 encodeBase64 = DECODER.decode(str);
190 } catch (Exception e) {
191 }
192 return encodeBase64;
193 }
194 }
195}
1#include <iostream>
2#include <map>
3#include <curl/curl.h>
4#include <cryptopp/aes.h>
5#include <cryptopp/filters.h>
6#include "json/json.h"
7#include "aip/base/base64.h"
8#include "cryptopp/hex.h"
9#include "openssl/aes.h"
10#include <openssl/evp.h>
11#include <fstream>
12
13#define KEY_SIZE_16B 16
14#define KEY_SIZE_24B 24
15#define KEY_SIZE_32B 32
16
17using CryptoPP::HexEncoder;
18using CryptoPP::HexDecoder;
19
20using CryptoPP::StringSource;
21
22// libcurl库下载链接:https://curl.haxx.se/download.html
23// jsoncpp库下载链接:https://github.com/open-source-parsers/jsoncpp/
24//const static std::string request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
25//获取token
26inline size_t onWriteData(void *buffer, size_t size, size_t nmemb, void *userp) {
27 std::string *str = dynamic_cast<std::string *>((std::string *) userp);
28 str->append((char *) buffer, size * nmemb);
29 return nmemb;
30}
31
32int get_token(
33 std::string ak,
34 std::string sk,
35 std::string *token) {
36 CURL *curl = curl_easy_init();
37 struct curl_slist *slist = NULL;
38 std::map<std::string, std::string> params;
39 std::string response;
40 std::string error;
41 params["grant_type"] = "client_credentials";
42 params["client_id"] = ak;
43 params["client_secret"] = sk;
44 std::string url = "https://aip.baidubce.com/oauth/2.0/token?"
45 "grant_type=client_credentials&client_id=" + ak + "&client_secret=" + sk;
46 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
47 curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
48 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
49 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
50 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
51 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT_MS, 2000);
52 curl_easy_setopt(curl, CURLOPT_TIMEOUT_MS, 2000);
53 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
54 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, false);
55 curl_easy_setopt(curl, CURLOPT_VERBOSE, false);
56 int status_code = curl_easy_perform(curl);
57 curl_easy_cleanup(curl);
58 curl_slist_free_all(slist);
59 Json::CharReaderBuilder crbuilder;
60 std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
61 Json::Value obj;
62 reader->parse(response.data(), response.data() + response.size(), &obj, &error);
63 *token = obj["access_token"].asString();
64
65 return status_code;
66}
67
68
69std::string JsonToString(const Json::Value &root) {
70 static Json::Value def = []() {
71 Json::Value def;
72 Json::StreamWriterBuilder::setDefaults(&def);
73 def["emitUTF8"] = true;
74 return def;
75 }();
76
77 std::ostringstream stream;
78 Json::StreamWriterBuilder stream_builder;
79 stream_builder.settings_ = def;//Config emitUTF8
80 std::unique_ptr<Json::StreamWriter> writer(stream_builder.newStreamWriter());
81 writer->write(root, &stream);
82 return stream.str();
83}
84
85
86int hex_char_value(char c) {
87 if (c >= '0' && c <= '9')
88 return c - '0';
89 else if (c >= 'a' && c <= 'f')
90 return (c - 'a' + 10);
91 else if (c >= 'A' && c <= 'F')
92 return (c - 'A' + 10);
93 assert(0);
94 return 0;
95}
96
97std::string get_key(std::string res) {
98 std::string lvStr;
99 for (int i = 0; i < 16; i++) {
100 int x = hex_char_value(res[i]);
101 char c = x;
102 std::cout << c;
103 lvStr.append(1, c);
104 }
105 return lvStr;
106}
107
108std::string ecb_encrypt(std::string res, std::string source) {
109 int outlen = 0;
110 int i = source.size() / 16;
111 int tail = source.size() % 16;
112 if (tail > 0) {
113 i++;
114 }
115 unsigned char encData[16 * i];
116 EVP_CIPHER_CTX *ctx;
117 ctx = EVP_CIPHER_CTX_new();
118 EVP_CipherInit_ex(ctx, EVP_aes_128_ecb(), NULL,
119 reinterpret_cast<const unsigned char *>(get_key(res).c_str()), NULL, 1);
120 EVP_CipherUpdate(ctx, encData, &outlen, reinterpret_cast<const unsigned char *>(source.c_str()), source.size());
121 EVP_CipherFinal(ctx, encData + outlen, &outlen);
122 EVP_CIPHER_CTX_free(ctx);
123 std::string data = aip::base64_encode(reinterpret_cast<const char *>(encData), sizeof(encData));
124 return data;
125}
126
127std::string ecb_decrypt(std::string res, std::string decode) {
128 std::string data = aip::base64_decode(decode);
129 int decLen = 0;
130 int outlen = 0;
131 unsigned char decData[data.size()];
132 EVP_CIPHER_CTX *ctx2;
133 ctx2 = EVP_CIPHER_CTX_new();
134 EVP_CipherInit_ex(ctx2, EVP_aes_128_ecb(), NULL, reinterpret_cast<const unsigned char *>(get_key(res).c_str()),
135 NULL, 0);
136 EVP_CipherUpdate(ctx2, decData, &outlen, reinterpret_cast<const unsigned char *>(data.c_str()), data.size());
137 decLen = outlen;
138 EVP_CipherFinal(ctx2, decData + outlen, &outlen);
139 decLen += outlen;
140 EVP_CIPHER_CTX_free(ctx2);
141 decData[decLen] = '\0';
142 printf("decrypt: %s\n", decData);
143 std::string result;
144 result = reinterpret_cast<const char *>(decData);
145 return result;
146}
147
148template<class CharT, class Traits, class Allocator>
149std::basic_istream<CharT, Traits> &getall(std::basic_istream<CharT, Traits> &input,
150 std::basic_string<CharT, Traits, Allocator> &str) {
151 std::ostringstream oss;
152 oss << input.rdbuf();
153 str.assign(oss.str());
154 return input;
155}
156
157inline int get_file_content(const char *filename, std::string *out) {
158 std::ifstream in(filename, std::ios::in | std::ios::binary);
159 if (in) {
160 getall(in, *out);
161 return 0;
162 } else {
163 return -1;
164 }
165}
166
167/**
168 * 身份证识别
169 * @return 调用成功返回0,发生错误返回其他错误码
170 */
171Json::Value idcard(const std::string &access_token) {
172 Json::Value obj;
173 std::string url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + access_token;
174 CURL *curl = NULL;
175 CURLcode result_code;
176 //图片内容
177 std::string file_content;
178 get_file_content("/Users/lidang/pyproject/baidu/aip/api-python-sdk/test/resources/my.jpg", &file_content);
179// std::string base64 = aip::base64_encode(file_content.c_str(), (int) file_content.size());
180 std::string res = "e1ad10e3d69689e0";
181 std::string base64 = ecb_encrypt(res, file_content);
182 int is_success;
183 std::string response;
184 std::string error;
185 curl = curl_easy_init();
186 if (curl) {
187 curl_easy_setopt(curl, CURLOPT_URL, url.data());
188 curl_easy_setopt(curl, CURLOPT_POST, 1);
189 curl_httppost *post = NULL;
190 curl_httppost *last = NULL;
191 curl_formadd(&post, &last, CURLFORM_COPYNAME, "id_card_side", CURLFORM_COPYCONTENTS, "front", CURLFORM_END);
192 curl_formadd(&post, &last, CURLFORM_COPYNAME, "image", CURLFORM_COPYCONTENTS, base64.c_str(), CURLFORM_END);
193 curl_formadd(&post, &last, CURLFORM_COPYNAME, "AESEncry", CURLFORM_COPYCONTENTS, "true", CURLFORM_END);
194 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
195 curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
196 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, onWriteData);
197 result_code = curl_easy_perform(curl);
198 if (result_code != CURLE_OK) {
199 fprintf(stderr, "curl_easy_perform() failed: %s\n",
200 curl_easy_strerror(result_code));
201 is_success = 1;
202 return is_success;
203 }
204 Json::CharReaderBuilder crbuilder;
205 std::unique_ptr<Json::CharReader> reader(crbuilder.newCharReader());
206 reader->parse(response.data(), response.data() + response.size(), &obj, &error);
207 curl_easy_cleanup(curl);
208 is_success = 0;
209 return obj;
210 } else {
211 fprintf(stderr, "curl_easy_init() failed.");
212 is_success = 1;
213 }
214 return obj;
215}
216
217int main() {
218
219// aipt::test_ocr();
220// aipt::test_kg();
221// aipt::test_speech();
222// aipt::test_face();
223// aipt::test_nlp();
224// aipt::test_ocr();
225// aipt::test_image_censor();
226// aipt::run_test(1);
227 std::string ak = "ak";
228 std::string sk = "sk";
229 std::string res = "控制台的aeskey";
230 std::string output;
231 std::string token;
232 get_token(ak, sk, &token);
233 Json::Value result;
234 result = idcard(token);
235 std::cout << result["result"];
236 std::string data = ecb_decrypt(res, result["result"].asString());
237 std::cout << data + "\n";
238// std::string encate = ecb_encrypt(res, "123456789123456789");
239// std::cout << encate + "\n";
240// std::string decode = ecb_decrypt(res,encate);
241// std::cout << decode+"\n";
242 return 0;
243}
1<?php
2
3function buildUrl($url, $params)
4{
5 if (!empty($params)) {
6 $str = http_build_query($params);
7 return $url . (strpos($url, '?') === false ? '?' : '&') . $str;
8 } else {
9 return $url;
10 }
11}
12
13function buildHeaders($headers)
14{
15 $result = array();
16 foreach ($headers as $k => $v) {
17 $result[] = sprintf('%s:%s', $k, $v);
18 }
19 return $result;
20}
21
22function get($url, $params = array(), $headers = array())
23{
24 $url = buildUrl($url, $params);
25
26 $headers = array_merge($headers, buildHeaders($headers));
27
28 $ch = curl_init();
29 curl_setopt($ch, CURLOPT_URL, $url);
30 curl_setopt($ch, CURLOPT_HEADER, false);
31 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
32 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
33 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
34 $content = curl_exec($ch);
35 $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
36
37 if ($code === 0) {
38 throw new Exception(curl_error($ch));
39 }
40
41 curl_close($ch);
42 return array(
43 'code' => $code,
44 'content' => $content,
45 );
46}
47
48function post($url, $data = array(), $headers = array())
49{
50 $ch = curl_init();
51 var_dump($url);
52 curl_setopt($ch, CURLOPT_URL, $url);
53 curl_setopt($ch, CURLOPT_POST, 1);
54 curl_setopt($ch, CURLOPT_HEADER, false);
55 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
56 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
57 curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
58 curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($data) ? http_build_query($data) : $data);
59
60 $content = curl_exec($ch);
61 $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
62
63 if ($code === 0) {
64 throw new Exception(curl_error($ch));
65 }
66
67 curl_close($ch);
68 return array(
69 'code' => $code,
70 'content' => $content,
71 );
72}
73
74function decrypt($sStr, $key)
75{
76 $sStr = base64_decode($sStr);
77 $decrypted = openssl_decrypt($sStr, 'AES-128-ECB', get_key($key), OPENSSL_RAW_DATA);
78 return $decrypted;
79}
80
81function encrypt($input, $key)
82{
83 $data = openssl_encrypt($input, 'AES-128-ECB', get_key($key), OPENSSL_RAW_DATA);
84 $data = base64_encode($data);
85 return $data;
86}
87
88function bytesToStr($bytes)
89{
90 $str = '';
91 foreach ($bytes as $ch) {
92 $str .= chr($ch);
93 }
94 return $str;
95}
96
97function get_key($key)
98{
99 $arr = str_split($key);
100 $bytes = array();
101 for ($i = 0; $i < count($arr); $i++) {
102 $bytes[] = ord(chr(hexdec($arr[$i])));
103 }
104 return bytesToStr($bytes);
105}
106
107$ak = "ak";
108$sk = "sk";
109#aes key 从控制台 文字识别-应用列表-应用管理 获取
110$aes = 'res';
111$response = get('https://aip.baidubce.com/oauth/2.0/token', array(
112 'grant_type' => 'client_credentials',
113 'client_id' => $ak,
114 'client_secret' => $sk,
115));
116$obj = json_decode($response['content'], true);
117
118$token = $obj['access_token'];
119$url = 'https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=' . $token;
120$img = file_get_contents('idcard.jpg');
121$img_data = encrypt($img, $aes);
122
123$data = array();
124$data['image'] = $img_data;
125$data['id_card_side'] = 'front';
126$data['AESEncry'] = 'true';
127
128$response = post($url, $data, array());
129$result =$response['content'];
130$book = json_decode($result,true);
131$res=decrypt($book["result"],$aes);
132echo $res;
133//构造请求数据json_decode($ content, true);
1using System;
2using NUnit.Framework;
3using System.Text;
4using System.Security.Cryptography;
5using System.IO;
6using System.Net;
7using System.Collections.Generic;
8using Newtonsoft.Json;
9using Newtonsoft.Json.Linq;
10using System.Linq;
11namespace Baidu.Aip
12{
13 [TestFixture]
14 public class Demo
15 {
16
17
18 public static byte[] getFileByte(String fileName)
19 {
20 FileStream filestream = new FileStream(fileName, FileMode.Open);
21 byte[] arr = new byte[filestream.Length];
22 filestream.Read(arr, 0, (int)filestream.Length);
23 filestream.Close();
24 return arr;
25 }
26 public static string ParseQueryString(Dictionary<string, string> querys)
27 {
28 if (querys.Count == 0)
29 return "";
30 return querys
31 .Select(pair => pair.Key + "=" + pair.Value)
32 .Aggregate((a, b) => a + "&" + b);
33 }
34 public static string StreamToString(Stream ss, Encoding enc)
35 {
36 string ret;
37 using (var reader = new StreamReader(ss, enc))
38 {
39 ret = reader.ReadToEnd();
40 }
41 ss.Close();
42 return ret;
43 }
44 public static JObject OpenApiFetchToken(string ak, string sk, bool throws = false, bool debugLog = false)
45 {
46 var querys = new Dictionary<string, string>
47 {
48 {"grant_type", "client_credentials"},
49 {"client_id", ak},
50 {"client_secret", sk}
51 };
52 var url = string.Format("{0}?{1}", "https://aip.baidubce.com/oauth/2.0/token", ParseQueryString(querys));
53 if (debugLog)
54 Console.WriteLine(url);
55 var webReq = (HttpWebRequest)WebRequest.Create(url);
56 try
57 {
58 var resp = (HttpWebResponse)webReq.GetResponse();
59 if (resp.StatusCode == HttpStatusCode.OK)
60 {
61 var respStr = StreamToString(resp.GetResponseStream(), Encoding.UTF8);
62 var obj = JsonConvert.DeserializeObject(respStr) as JObject;
63 if (obj["access_token"] != null && obj["expires_in"] != null)
64 return obj;
65 if (throws)
66 throw new AipException("Failed to request token. " + (string)obj["error_description"]);
67 return null;
68 }
69 if (throws)
70 throw new AipException("Failed to request token. " + resp.StatusCode + resp.StatusDescription);
71 }
72 catch (Exception e)
73 {
74 if (throws)
75 throw new AipException("Failed to request token. " + e.Message);
76 return null;
77 }
78
79 return null;
80 }
81 public static string UrlEncode(string str)
82 {
83 StringBuilder sb = new StringBuilder();
84 byte[] byStr = System.Text.Encoding.UTF8.GetBytes(str); //默认是System.Text.Encoding.Default.GetBytes(str)
85 for (int i = 0; i < byStr.Length; i++)
86 {
87 sb.Append(@"%" + Convert.ToString(byStr[i], 16));
88 }
89
90 return (sb.ToString());
91 }
92 public static string Encrypt(string toEncrypt, string key)
93 {
94 byte[] keyArray = GetKey(key);
95 byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
96 Console.WriteLine("Hello World!" + keyArray.Length);
97 RijndaelManaged rDel = new RijndaelManaged();
98 rDel.Key = keyArray;
99 rDel.Mode = CipherMode.ECB;
100 rDel.Padding = PaddingMode.PKCS7;
101
102 ICryptoTransform cTransform = rDel.CreateEncryptor();
103 byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
104
105 return Convert.ToBase64String(resultArray, 0, resultArray.Length);
106 }
107 public static string Encrypt(byte[] toEncryptArray, string key)
108 {
109 byte[] keyArray = GetKey(key);
110 Console.WriteLine("Hello World!" + keyArray.Length);
111 RijndaelManaged rDel = new RijndaelManaged();
112 rDel.Key = keyArray;
113 rDel.Mode = CipherMode.ECB;
114 rDel.Padding = PaddingMode.PKCS7;
115
116 ICryptoTransform cTransform = rDel.CreateEncryptor();
117 byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
118
119 return Convert.ToBase64String(resultArray, 0, resultArray.Length);
120 }
121 public static byte[] GetKey(string key)
122 {
123 byte[] result = new byte[key.Length];
124 char[] array = key.ToArray();
125 int i = 0;
126 for (int a = 0; a < array.Length; a = a + 1)
127 {
128 string ch =array[a]+"";
129 int val=Convert.ToInt32(ch,16);
130 result[a] = (byte)val;
131 }
132 return result;
133 }
134
135
136
137 /*
138 * AES解密
139 * */
140 public static string Decrypt(string toDecrypt, string key)
141 {
142 byte[] keyArray = GetKey(key);
143 byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);
144
145 RijndaelManaged rDel = new RijndaelManaged();
146 rDel.Key = keyArray;
147 rDel.Mode = CipherMode.ECB;
148 rDel.Padding = PaddingMode.PKCS7;
149
150 ICryptoTransform cTransform = rDel.CreateDecryptor();
151 byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
152
153 return UTF8Encoding.UTF8.GetString(resultArray);
154 }
155
156 [Test]
157 public void demo()
158 {
159 string res = "控制台的aeskey";
160 string ak = "ak";
161 string sk = "sk";
162
163 string host = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + OpenApiFetchToken(ak, sk)["access_token"];
164 //Console.WriteLine("url:"+host);
165 Encoding encoding = Encoding.Default;
166 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(host);
167 request.Method = "post";
168 request.KeepAlive = true;
169 //// 图片的base64编码
170 byte[] file = getFileByte("图片路径");
171 string base64= Encrypt(file, res);
172 string str = "AESEncry=true&id_card_side=" + "front" + "&image=" + UrlEncode(base64);
173 byte[] buffer = encoding.GetBytes(str);
174 request.ContentLength = buffer.Length;
175 request.GetRequestStream().Write(buffer, 0, buffer.Length);
176 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
177 StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.Default);
178 string result = reader.ReadToEnd();
179 Console.WriteLine("身份证识别:");
180 Console.WriteLine(result);
181 Console.WriteLine("解密");
182 var obj = JsonConvert.DeserializeObject(result) as JObject;
183 var content=Decrypt((string)obj["result"], res);
184 Console.WriteLine(content);
185 }
186}
187}
返回说明
返回示例
1{
2 "log_id":"2648325511",
3 "result":"密文"
4}
请对result密文进行base64解码后得到byte流,再进行AES解密,得到识别结果的明文。