用Go语言在Linux下调用新中新DKQ-A16D读卡器,读二代证数据
1.背景
前几天用Python在Linux下成功的获取了二代证数据,最近正在学Go语言,这两天想着用Go语言也实现一下试看看。
2.开搞C++
这次就比较简单了,直接把CppDemo里面的SynReader.h拿来就可以,还有就是把CppDemo里面的lib文件也复制过来就可以,
具体流程和Python那篇文章的一样
被我精简后的SynReader.h
1 #ifndef SYN_READER_H 2 #define SYN_READER_H 3 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 9 10 #pragma pack(1) 11 12 typedef struct IDCardDataUTF8 { 13 char CardType[10]; //I为外国人居住证,J 为港澳台居住证,空格(0x20)为普通身份证 14 char Name[40]; //姓名 15 char EngName[130]; //英文名(外国人居住证) 16 char Sex[10]; //性别 17 char Nation[100]; //民族或国籍(外国人居住证) 18 char Birthday[18]; //出生日期 19 char Address[80]; //住址 20 char IDCardNo[40]; //身份证号或外国人居住证号(外国人居住证) 21 char GrantDept[40]; //发证机关 22 char UserLifeBegin[30]; //有效开始日期 23 char UserLifeEnd[30]; //有效截止日期 24 char PassID[30]; //通行证号码(港澳台) 25 char IssuesTimes[10]; //签发次数(港澳台) 26 char CertVol[10]; //证件版本号(外国人居住证) 27 char wlt[1024]; //照片数据 28 int isSavePhotoOK; //照片是否解码保存 0=no 1=yes 29 char fp[1024]; //指纹数据 30 int isFpRead; //是否读取了证内指纹 0=no 1=yes 31 } St_IDCardDataUTF8, *PSt_IDCardDataUTF8; 32 #pragma pack() 33 34 //读身份证文字和照片信息 35 int getIDcard(St_IDCardDataUTF8 *pIDCardDataUTF8); 36 37 int OpenUsbComm(); 38 int OpenSerialComm(const char*); 39 int CloseComm(); 40 41 42 //解码照片函数,wltBuffer原始照片1024字节wlt数据,bmpPath 保存照片位置 43 int saveWlt2Bmp( char* wltBuffer,const char* bmpPath); 44 int saveWlt2BmpUseFork( char* wltBuffer,const char* bmpPath); 45 46 //获取动态库版本 47 const char* getLibVersion(); 48 int getLibVersionInt(); 49 50 51 52 #ifdef __cplusplus 53 } 54 #endif 55 56 #endif
3.开搞Go
直接上代码了,大概的分析和Python的差不多,在Go语言中,主要是用到import “C”这个东东来调用C语言里面的函数
main.go
1 package main 2 3 /* 4 #cgo LDFLAGS: -L ./lib -lSynReader64 5 #include "../include/SynReader64.h" 6 */ 7 import "C" 8 import ( 9 "fmt" 10 "unsafe" 11 ) 12 13 /* 14 CArrayToGoString 将C语言中的字符数组转为Go语言的string 15 */ 16 func CArrayToGoString(cArray unsafe.Pointer, size int) (goStr string) { 17 p := uintptr(cArray) 18 var goArray []byte 19 for i := 0; i < size; i++ { 20 j := *(*byte)(unsafe.Pointer(p)) 21 goArray = append(goArray, j) 22 p += unsafe.Sizeof(j) 23 } 24 25 return string(goArray) 26 } 27 28 func main() { 29 30 var stIDCardDataUTF8 C.struct_IDCardDataUTF8 31 32 openState := C.OpenUsbComm() 33 34 if openState == 0 { 35 getState := C.getIDcard(&stIDCardDataUTF8) 36 37 if getState == 0 { 38 strName := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.Name), 40) 39 strSex := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.Sex), 10) 40 strNation := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.Nation), 100) 41 strBirthday := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.Birthday), 18) 42 strAddress := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.Address), 80) 43 strIDCardNo := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.IDCardNo), 40) 44 strGrantDept := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.GrantDept), 40) 45 strUserLifeBegin := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.UserLifeBegin), 30) 46 strUserLifeEnd := CArrayToGoString(unsafe.Pointer(&stIDCardDataUTF8.UserLifeEnd), 30) 47 48 fmt.Println(strName) 49 fmt.Println(strSex) 50 fmt.Println(strNation) 51 fmt.Println(strBirthday) 52 fmt.Println(strAddress) 53 fmt.Println(strIDCardNo) 54 fmt.Println(strGrantDept) 55 fmt.Println(strUserLifeBegin) 56 fmt.Println(strUserLifeEnd) 57 58 photoData := unsafe.Pointer(&stIDCardDataUTF8.wlt) 59 C.saveWlt2BmpUseFork((*C.char)(photoData), C.CString("Photo.bmp")) 60 } 61 62 } 63 C.CloseComm() 64 65 }
其中注意,第4行,作用是引入so库,-l参数后面加so文件名(不含.so)
第5行是引入C++定义的头文件
具体路径目录如下:
├── include
│ └── SynReader64.h
├── libx64
│ ├── libSynReader64.so
│ ├── libusb-1.0.so
│ └── libwlt.so
└── src
├── main
└── main.go
4.结束
接着想实现用Python或者Go语言作为http服务器,将该刷卡服务以http方式返回json信息,这样就可以实现不使用浏览器插件,以及跨浏览器刷卡。敬请期待……