百度AI的使用:解析身份证

百度AI的使用:解析身份证

附百度AI解析身份证接口文档      

百度API提供的几个工具类

解析身份证需要百度应用ID(clientId)和百度应用的秘钥(clientSecret)。附官网链接地址


package com.test.www;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSONObject;
import com.test.util.BaiDu_Base64Util;
import com.test.util.HttpUtil_BaiDu;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import com.jpay.util.StringUtils;

@Controller
@RequestMapping("/upload")
public class upload {

    private static final Logger logger = LoggerFactory.getLogger(upload.class);
    
    //百度解析身份证的接口地址
    private static String idcardIdentificate = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
    //百度解析身份获取token地址
    private static String authHost = "https://aip.baidubce.com/oauth/2.0/token";
    //官网获取的 API Key
    private static String clientId = "***********NquAegus****";
    //官网获取的 Secret Key
    private static String clientSecret = "XfPMY5Rgi*************Avsng1yK";
    
    /**
     * 上传图片
     * @param request
     * @param response
     * @param file 
     * @param idCardType   身份证正反面
     * @param idCard	   身份证
     * @param name         姓名
     * @param sex		   性别
     * @return			自己组装数据
     */
    @RequestMapping(value = "/upload")
    @ResponseBody
    public result uploadImage(HttpServletRequest request, HttpServletResponse response,
            @RequestParam(value = "file", required = false) MultipartFile file,
            @RequestParam(value = "idCardType", required = true) String idCardType,
            @RequestParam(value = "idCard", required = true) String idCard,
            @RequestParam(value = "name", required = true) String name,
            @RequestParam(value = "sex", required = true) String sex) {
        if (!file.isEmpty() || StringUtils.isNotBlank(idCardType)) {
            String fileName = file.getOriginalFilename();
            String path = null;
            String imgType = null;
            imgType = Files.getFileExtension(fileName).toUpperCase();
            if ("PNG".equals(imgType) || "JPG".equals(imgType) || "BMP".equals(imgType)) {
                // 验证身份证信息
                long begin = System.currentTimeMillis();
                result resultJson = validateIdCard(file,
                        idCardType.equals("front") ? "front" : "back",
                        idCard, name, sex);
                long end = System.currentTimeMillis();
                logger.info("==========验证身份证花费时间:" + (end - begin) / 1000 + "s");
                //判断验证身份证是否成功
                if (!resultJson.boo) {
                    return resultJson;
                }
                // 根路径
                String realPath = request.getSession().getServletContext().getRealPath("/");
                // 文件名字
                String trueFileName = idCard + "_" + idCardType + "." + imgType;
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
                String dateString = sdf.format(new Date());
                // 存放路径
                String relativePath = "uploads" + File.separator + "idCard" + File.separator
                        + dateString + File.separator;
                path = realPath + relativePath;
                try {
                    // 创建存放的文件
                    File dir = new File(path);
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
                    path += trueFileName;
                    File f = new File(path);
                    file.transferTo(f);
                    path = URLDecoder.decode(path, "UTF-8");
                    logger.info("图片存放的路径为:" + path);
                    return new result(Boolean.TRUE, relativePath + trueFileName, "上传成功!");
                } catch (IllegalStateException | IOException e) {
                    logger.error("", e);
                    return new result(Boolean.FALSE, null, "图片上传失败!");
                }
            } else {
                logger.info("图片类型不匹配!");
                return new result(Boolean.FALSE, null, "图片类型不匹配!");
            }
        } else {
            logger.info("图片为空!");
            return new result(Boolean.FALSE, null, "图片为空!");
        }
    }



    /**
     * 验证上传身份证的正确性
     * 
     * @return
     */
    private result validateIdCard(MultipartFile file, String idCardSide, String idCard,
            String name, String sex) {
        String accessToken = getAuth();
        String result = null;
        try {
            byte[] imgData = file.getBytes();
            String imgStr = BaiDu_Base64Util.encode(imgData);
            // 识别身份证正面id_card_side=front,识别身份证背面id_card_side=back;
            String params = "id_card_side=" + idCardSide + "&" + URLEncoder.encode("image", "UTF-8")
                    + "=" + URLEncoder.encode(imgStr, "UTF-8");
            result = HttpUtil_BaiDu.post(idcardIdentificate, accessToken, params);
            JSONObject jsonObject = JSONObject.parseObject(result);
            // 身份证正面
            if (idCardSide.equals("front")) {
                JSONObject wordsResult = jsonObject.getJSONObject("words_result");
                Map<String, String> resultMap = getMapByFront(wordsResult);
                logger.info("解析正面的信息为:", resultMap);
                if (resultMap.isEmpty()) {
                    return new result(Boolean.FALSE, null, "解析正面失败!");
                }
                if (StringUtils.isEmpty(resultMap.get("name"))) {
                    return new result(Boolean.FALSE, null, "解析姓名失败!");
                }
                if (StringUtils.isEmpty(resultMap.get("sex"))) {
                    return new result(Boolean.FALSE, null, "解析姓别失败!");
                }
                if (StringUtils.isEmpty(resultMap.get("card"))) {
                    return new result(Boolean.FALSE, null, "解析证件号码失败!");
                }
                if (!resultMap.get("name").equals(name)) {
                    return new result(Boolean.FALSE, null, "姓名不符!");
                }
                if (!resultMap.get("sex").equals(sex)) {
                    return new result(Boolean.FALSE, null, "姓别不符!");
                }
                if (!resultMap.get("card").equals(idCard)) {
                    return new result(Boolean.FALSE, null, "证件号码不符!");
                }
                return new result(Boolean.TRUE, resultMap, "解析正面成功!");
            } else {
                // 身份证反面
                JSONObject wordsResult = jsonObject.getJSONObject("words_result");
                Map<String, String> resultMap = getMapByBlack(wordsResult);
                if (resultMap.isEmpty()) {
                    return new result(Boolean.FALSE, null, "解析反面失败!");
                }
                if (StringUtils.isBlank(resultMap.get("organization"))) {
                    return new result(Boolean.FALSE, null, "签发机关解析失败!");
                }
                if (StringUtils.isBlank(resultMap.get("endDate"))) {
                    return new result(Boolean.FALSE, null, "结束日期解析失败!");
                }
                if (StringUtils.isBlank(resultMap.get("beginDate"))) {
                    return new result(Boolean.FALSE, null, "开始时间解析失败!");
                }
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
                Date endDate = sdf.parse(resultMap.get("endDate"));
                // 身份证过期
                if (new Date().after(endDate)) {
                    return new result(Boolean.FALSE, null, "证件已经过期!");
                } else {
                    return new result(Boolean.TRUE, resultMap, "解析反面成功!");
                }
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 解析身份证反面信息
     * 
     * @param wordsResult
     * @return
     */
    public static HashMap<String, String> getMapByFront(JSONObject wordsResult) {
        HashMap<String, String> map = Maps.newHashMap();
        try {
            Set<String> set = wordsResult.keySet();
            Iterator<String> it = set.iterator();
            while (it.hasNext()) {
                String key = it.next();
                JSONObject result = wordsResult.getJSONObject(key);
                String value = result.getString("words");
                switch (key) {
                    case "姓名":
                        map.put("name", value);
                        break;
                    case "民族":
                        map.put("nation", value);
                        break;
                    case "住址":
                        map.put("address", value);
                        break;
                    case "公民身份号码":
                        map.put("card", value);
                        break;
                    case "出生":
                        map.put("birth", value);
                        break;
                    case "性别":
                        map.put("sex", value);
                        break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 解析身份证反面信息
     * 
     * @param wordsResult
     * @return
     */
    public static HashMap<String, String> getMapByBlack(JSONObject wordsResult) {
        HashMap<String, String> map = new HashMap<String, String>();
        try {
            Set<String> set = wordsResult.keySet();
            Iterator<String> it = set.iterator();
            while (it.hasNext()) {
                String key = it.next();
                JSONObject result = wordsResult.getJSONObject(key);
                String value = result.getString("words");
                switch (key) {
                    case "签发机关":
                        map.put("organization", value);
                        break;
                    case "失效日期":
                        map.put("endDate", value);
                        break;
                    case "签发日期":
                        map.put("beginDate", value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 获取权限token
     * 
     * @return 返回示例: { "access_token":
     *         "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567",
     *         "expires_in": 2592000 }
     */
    public String getAuth() {
    	String auth = getAuth(clientId, clientSecret);
    	if(StringUtils.isEmpty(auth)){
    		return getAuth(clientId, clientSecret);
    	}else{
    		return auth;
    	}
    }

    /**
     * 获取API访问token 该token有一定的有效期,需要自行管理,当失效时需重新获取.
     * 
     * @param ak - 百度云官网获取的 API Key
     * @param sk - 百度云官网获取的 Securet Key
     * @return assess_token 示例:
     *         "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
     */
    public String getAuth(String ak, String sk) {
        String getAccessTokenUrl = authHost
                // 1. grant_type为固定参数
                + "?grant_type=client_credentials"
                // 2. 官网获取的 API Key
                + "&client_id=" + ak
                // 3. 官网获取的 Secret Key
                + "&client_secret=" + sk;
        try {
            URL realUrl = new URL(getAccessTokenUrl);
            // 打开和URL之间的连接
            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.err.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            BufferedReader in =
                    new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String result = "";
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
            /**
             * 返回结果示例
             */
            System.err.println("result:" + result);

            JSONObject jsonObject = JSONObject.parseObject(result);
            String access_token = jsonObject.getString("access_token");
            return access_token;
        } catch (Exception e) {
            System.err.printf("获取token失败!");
            e.printStackTrace(System.err);
        }
        return null;
    }

    /**
     * 组装结果集
     */
    @SuppressWarnings("unused")
    class result {
    	private boolean boo = true;
	private Object result;
        private String messages;
        public result(boolean boo, Object result, String messages) {
            this.boo = boo;
            this.result = result;
            this.messages = messages;
        }
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值