二代身份证读卡器的二次开发(jni)

cnmghi 2008-05-12 02:00:37
客户提供一台读卡器、sdtapi.dll、WltRS.dll,以及相应的头文件,我是通过java的jni与所写c++代码进行交互,但是java这边接收到的身份证基本信息一直是乱码。先说明c++向java传其他中文不会出现乱码,是在c++读出的身份证信息就是乱码。c++的代码如下:
#include "windows.h"
#include "CardReader.h"
#include "sdtapi.h"
#include "String.h"
#include "WltRS.h"


JNIEXPORT jbyteArray JNICALL Java_CardReader_getMessage(JNIEnv * env, jobject jobj){

char* szStr="mei zhao dao xin xi";
char cInput;
int iRet; //返回码
int iPort; //端口号
int iIfOpen=0; //是否需要打开串口
unsigned char pucIIN[8];
unsigned char pucSN[8];
unsigned char pucCHMsg[512]; //文字信息
unsigned char pucPHMsg[1024]; //照片信息
unsigned char pucFPMsg[1024]; //指纹信息
unsigned int uiCHMsgLen,uiPHMsgLen;

memset(pucCHMsg,0,sizeof(pucCHMsg));
int length;
jbyteArray RtnArr = NULL;
jsize arrsize;

if(iIfOpen==0){

for (iPort = 1001; iPort <= 1016; iPort++)
{
iRet=SDT_OpenPort(iPort);
printf("SDT_OpenPort usb error, error code is: %02x\n", iRet);
printf("SDT_OpenPort usb error, error code is: %02d\n", iPort);
if(iRet==0x90) break;
}


if(iRet!=0x90)
{

printf("SDT_OpenPort error, error code is: %02x\n", iRet);
SDT_ClosePort(iPort);
szStr="SDT_OpenPort error";
printf(szStr);
length = strlen(szStr);
arrsize =(jsize)length;

RtnArr=env->NewByteArray(arrsize);
env->SetByteArrayRegion(RtnArr, 0,length, (jbyte*)szStr);

return RtnArr;

}

iRet=SDT_StartFindIDCard(iPort,pucIIN, iIfOpen);
printf("SDT_StartFindIDCard error, error code is: %02x\n", iRet);
if (iRet != 0x9f)
{
iRet=SDT_StartFindIDCard(iPort,pucIIN, iIfOpen); //再找卡
if (iRet != 0x9f)
{
iRet = SDT_ClosePort(iPort);
printf("SDT_StartFindIDCard error, error code is: %02x\n", iRet);
szStr="SDT_StartFindIDCard error";
length = strlen(szStr);
arrsize =(jsize)length;

RtnArr=env->NewByteArray(arrsize);
env->SetByteArrayRegion(RtnArr, 0,length, (jbyte*)szStr);

return RtnArr;
}
}

iRet=SDT_SelectIDCard (iPort,pucSN, iIfOpen);
printf("SDT_SelectIDCard error, error code is: %02x\n", iRet);
if (iRet != 0x90)
{
iRet=SDT_SelectIDCard (iPort,pucSN, iIfOpen); //再选卡
if (iRet != 0x90)
{
iRet = SDT_ClosePort(iPort);
printf("SDT_SelectIDCard error, error code is: %02x\n", iRet);
szStr="SDT_SelectIDCard error";
length = strlen(szStr);
arrsize =(jsize)length;

RtnArr=env->NewByteArray(arrsize);
env->SetByteArrayRegion(RtnArr, 0,length, (jbyte*)szStr);

return RtnArr;
}
}


iRet=SDT_ReadBaseMsg(iPort,pucCHMsg,&uiCHMsgLen, pucPHMsg,&uiPHMsgLen, iIfOpen);
printf("SDT_ReadBaseMsg error, error code is: %02x\n", iRet);

if(iRet!=0x90)
{
printf("SDT_ReadBaseMsg error, error code is: %02x\n", iRet);
if(iIfOpen==0)
SDT_ClosePort(iPort);
printf("ssaaaasasasaas\n");
szStr="SDT_ReadBaseMsg error";
length = strlen(szStr);
arrsize =(jsize)length;
RtnArr=env->NewByteArray(arrsize);
printf("123345453\n");
env->SetByteArrayRegion(RtnArr, 0,length, (jbyte*)szStr);
printf("12sssssssss33454534ssaaaasasasaas");
return RtnArr;
}
printf("SDT_ReadBaseMsg OK\n");
if(iIfOpen==0)
SDT_ClosePort(iPort);

RtnArr=env->NewByteArray(uiCHMsgLen);
printf("pucCHMsg=%s\n",pucCHMsg);
env->SetByteArrayRegion(RtnArr, 0,uiCHMsgLen, (jbyte*)pucCHMsg);

return RtnArr;
}

length = strlen(szStr);
arrsize =(jsize)length;
RtnArr=env->NewByteArray(arrsize);
env->SetByteArrayRegion(RtnArr, 0,length, (jbyte*)szStr);

return RtnArr;

}
...全文
842 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
同创云 2012-08-08
  • 打赏
  • 举报
回复
 基本信息处理
因为二代身份证里编码为GB13000,在java处理中存在问题,总体处理思想为先把16进制字节高地位互换,然后用UTF-16BE转换成中文字符代码如下
public static String hexByes2String(byte[] bytes,String charsetName){
if("".equals(charsetName)) charsetName="UTF-16BE";
try {
return new String(bytes,charsetName);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "";
}
public static byte[] hexBytesH2L(byte[] bytes)
{
byte tmp = 0;
for(int i=0;i<bytes.length;i++){

if(i%2==0) {
tmp=bytes[i];
bytes[i]=bytes[i+1];

}
else bytes[i]=tmp;

}
return bytes;
}
调用:hexByes2String(XSocketUtils.hexBytesH2L(hexBytes),"UTF-16BE")
 图片信息处理(用到jna.jar包)
图片信息处理必须调用第三方提供dll,GETINFO.DLL,过程是先在java中保存16进制字节为一个wlt文件在用GETINFO.DLL中的getBMP函数,生成bmp图片,在从bmp提取图片字节,函数如下(直接调用getPictureBytes即可)

import com.sun.jna.Library;
import com.sun.jna.Native;

public class GetSFZPic {
public interface CLibrary extends Library {
CLibrary wltToBmp = (CLibrary) Native.loadLibrary("GETINFO",CLibrary.class);
void GetBmp(String wltfile,int a);
}
private static void generatePictureBmp(byte[] picbytes,String idcard){
try {
String wltfile=System.getProperty( "user.dir")+"\\shxxcjxtzp.wlt";
if(null!=picbytes){
DataOutputStream out=new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(wltfile)));
out.write(picbytes);
out.close();
}
CLibrary.wltToBmp.GetBmp(wltfile, 1);
} catch (IOException e) {
e.printStackTrace();
}

}
public synchronized static byte[] getPictureBytes(byte[]picbytes,String idcard) {

String filename=System.getProperty( "user.dir")+"\\shxxcjxtzp.bmp";
generatePictureBmp(picbytes,idcard);
File file =new File(filename);
if(filename==null || filename.equals("")) {
throw new NullPointerException("无效的文件路径");
}
long len = file.length();
byte[] bytes = new byte[(int)len];
System.out.println(filename+"--------"+len);
BufferedInputStream bufferedInputStream;
try {
bufferedInputStream = new BufferedInputStream(new FileInputStream(file));
int r = bufferedInputStream.read( bytes );
if (r != len)
throw new IOException("读取文件不正确");
bufferedInputStream.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


return bytes;

}
}




TomyGuan 2008-05-13
  • 打赏
  • 举报
回复
http://linux.e800.com.cn/articles/2008/425/1209064282509769714_1.html

這里用來安裝CS
TomyGuan 2008-05-13
  • 打赏
  • 举报
回复
是Wine吧。一個適配層。
Wine軟件包模擬Windows環境

cnmghi 2008-05-13
  • 打赏
  • 举报
回复
回TomyGuan:老大,好好想一想是要装什么?万分感谢
TomyGuan 2008-05-13
  • 打赏
  • 举报
回复
Linux用不了是否考慮用web service呢?

Linux好你像裝了一個什么之後可以和window一樣用。但不記得那個名了。
cnmghi 2008-05-13
  • 打赏
  • 举报
回复
回guoqiangone:我用的不是嵌入式,呵呵,我是开发保险录单时候要用到读卡器。
cnmghi 2008-05-13
  • 打赏
  • 举报
回复
唉,现在又有一个问题,要把这个程序移植到linux上,但是客户提供的是两个dll文件,在linux是用不了的,linux动态链接库是用so文件
guoqiangone 2008-05-12
  • 打赏
  • 举报
回复
学习,我也想用java开发一个,lz用的嵌入式么。
树成 2008-05-12
  • 打赏
  • 举报
回复
我觉得,如果接口不是自己实现的,最好还是找开发者或者接口提供者以正当途径获得相关信息文档,不然用以引起不必要的麻烦。
身份证这种东西算是比较敏感的东西。
cnmghi 2008-05-12
  • 打赏
  • 举报
回复
我们只是读又不是要写,我觉得应该不用有关部门提供吧。不过经过加密倒是有可能。
树成 2008-05-12
  • 打赏
  • 举报
回复
那谁知道,身份证这东西不是随便谁就能读取的吧?
如果谁都能读取里面信息,那不是全乱套了?
不过也有可能不是某种编码保存,而是经过加密处理的,这些都很难说的,这需要相关部门提供信息才可以。
cnmghi 2008-05-12
  • 打赏
  • 举报
回复
那spiniper你估计身份证的基本信息是用什么编码存储的?
zr_dixuexiongying 2008-05-12
  • 打赏
  • 举报
回复
学习
树成 2008-05-12
  • 打赏
  • 举报
回复
我估计身份证中的中文编码和普通编码不同,要注意看一下是什么编码才行。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧