> **๐ Language:** English ยท [เนเธเธข](README.th.md)
# libthai-idcard
[](https://crates.io/crates/libthai-idcard)
[](https://github.com/phakhawatchu/libthai-idcard)
[](https://github.com/phakhawatchu/libthai-idcard/actions/workflows/ci.yml)
[](https://github.com/phakhawatchu/libthai-idcard/releases/latest)
[](https://github.com/phakhawatchu/libthai-idcard)
A Rust library for reading **Thai National ID smart cards** via PC/SC
smart card readers, with **C**, **C++**, **Go**, **Java**, **Kotlin**, **JavaScript**, **Python**, and **Ruby** usage examples.
## Overview
Thai National ID smart cards store citizen identification data, a JPEG face
photo, NHSO (National Health Security Office) insurance information, and a
laser-engraved card serial number. This library handles the low-level APDU
communication, TIS-620 (Thai) text decoding, and Buddhist-to-Gregorian date
conversion, exposing the data through a clean multi-language API.
### Features
- โ
Read citizen ID, name (Thai & English), date of birth, gender
- โ
Read registered address (parsed into components)
- โ
Read card issuer, issue date, expiry date
- โ
Read JPEG face photo (returned as base64)
- โ
Read laser-engraved card serial number
- โ
Read NHSO insurance data (main/sub hospitals, coverage dates, etc.)
- โ
Buddhist year โ Gregorian calendar conversion
- โ
TIS-620 (Windows-874) Thai text decoding
- โ
Auto-detect card reader or specify by name
- โ
Daemon mode for continuous card monitoring
- โ
C usage example (dynamic loading or link-time)
- โ
C++ usage example (via `dlopen`/`LoadLibrary`)
- โ
Go usage example (via `cgo`)
- โ
Java usage example (via `JNA`)
- โ
Kotlin usage example (via `JNA`)
- โ
JavaScript usage example (via `koffi`)
- โ
Python usage example (via `ctypes`)
- โ
Ruby usage example (via `fiddle`)
## Requirements
- **Hardware:** A PC/SC-compatible smart card reader and a Thai National ID card
- **Software:** PC/SC Lite (`pcsclite`) โ installed by default on macOS and most Linux distributions
- **macOS:** Built-in (`PCSC.framework`)
- **Linux:** `sudo apt install libpcsclite-dev` (Debian/Ubuntu) or `sudo dnf install pcsc-lite-devel` (Fedora)
- **Windows:** Winscard (built-in)
## Usage
### Rust
```rust
use thaiidcard::{SmartCard, Options};
let card = SmartCard::new();
let data = card.read(None, &Options::default()).unwrap();
let personal = data.personal.unwrap();
println!("Name: {}", personal.name.full_name);
println!("CID: {}", personal.cid);
println!("DOB: {}", personal.dob);
```
Or with a specific reader and extra data sections:
```rust
use thaiidcard::{SmartCard, Options};
let opts = Options {
show_nhso_data: true,
show_laser_data: true,
show_face_image: true,
..Default::default()
};
let card = SmartCard::new();
let data = card.read(Some("Identive USB Reader"), &opts).unwrap();
```
See [`examples/rust_usage.rs`](examples/rust_usage.rs) for a complete example.
### C
A C usage example is available at [`examples/c_usage.c`](examples/c_usage.c).
It demonstrates both dynamic loading (`dlopen`/`dlsym`) and compile-time
linking against the shared library.
```bash
# Dynamic loading (no linker flags)
cc -o c_usage examples/c_usage.c -ldl
./c_usage
# Compile-time linking
cc -o c_usage examples/c_usage.c -Ltarget/debug -lthaiidcard \
-lpcsclite -Wl,-rpath,target/debug
./c_usage
```
### C++
A C++ usage example is available at
[`examples/cpp_usage.cpp`](examples/cpp_usage.cpp).
It uses RAII wrappers and C++17 features to load the shared library
and read card data.
```bash
# macOS / Linux:
g++ -std=c++17 -o cpp_usage examples/cpp_usage.cpp -ldl
./cpp_usage
# Windows (MinGW):
g++ -std=c++17 -o cpp_usage.exe examples/cpp_usage.cpp
./cpp_usage
```
### Go
A Go usage example is available at
[`examples/go_usage.go`](examples/go_usage.go).
It uses `cgo` to load the shared library via `dlopen` and read card data.
```bash
go run examples/go_usage.go
```
### Java
A Java usage example is available at
[`examples/java_usage.java`](examples/java_usage.java).
It uses **JNA** (Java Native Access) to call the shared library functions.
```bash
# With jbang (auto-downloads JNA):
jbang examples/java_usage.java
# Or compile & run manually (download jna.jar first):
javac -cp jna.jar examples/java_usage.java
java -cp .:jna.jar java_usage
```
### Kotlin
A Kotlin usage example is available at
[`examples/kotlin_usage.kt`](examples/kotlin_usage.kt).
It uses **JNA** (Java Native Access) to call the shared library functions.
```bash
# With jbang (auto-downloads JNA):
jbang examples/kotlin_usage.kt
# Or compile & run manually (download jna.jar first):
kotlinc -cp jna.jar examples/kotlin_usage.kt
kotlin -cp .:jna.jar kotlin_usageKt
```
### JavaScript
A JavaScript usage example is available at
[`examples/js_usage.js`](examples/js_usage.js).
It uses **koffi** (a modern FFI library for Node.js) to call the shared
library functions.
```bash
npm install koffi
node examples/js_usage.js
```
### Python
A Python usage example is available at
[`examples/python_usage.py`](examples/python_usage.py).
It uses `ctypes` to load the shared library and read card data.
```bash
python3 examples/python_usage.py
```
### Ruby
A Ruby usage example is available at
[`examples/ruby_usage.rb`](examples/ruby_usage.rb).
It uses `fiddle` (Ruby's built-in FFI library) to load the shared library
and read card data.
```bash
ruby examples/ruby_usage.rb
```
## Building
```bash
# Build all Rust targets (library + examples)
make build
# Build only the native shared library (.dylib/.so/.dll)
make shared
# Generate C header file (requires cbindgen)
make headers
# Run the Rust usage example
make example
# Run the C example
make c-example
# Run the C++ example
make cpp-example
# Run the Go example
make go-example
# Run the Java example
make java-example
# Run the Kotlin example
make kotlin-example
# Run the JavaScript example
make js-example
# Run the Python example
make python-example
# Run the Ruby example
make ruby-example
```
### Pre-built Binaries
Pre-built shared libraries are available on the
[GitHub Releases page](https://github.com/phakhawatchu/libthai-idcard/releases/latest)
for the following platforms:
| Linux | x86_64 | `libthaiidcard-linux-x86_64.so` |
| Linux | ARM64 | `libthaiidcard-linux-arm64.so` |
| macOS | x86_64 (Intel) | `libthaiidcard-macos-x86_64.dylib` |
| macOS | ARM64 (Apple Silicon) | `libthaiidcard-macos-arm64.dylib` |
| Windows | x86_64 | `thaiidcard-windows-x86_64.dll` |
| Windows | ARM64 | `thaiidcard-windows-arm64.dll` |
### Cross-compilation
All cross-compilation targets use Docker (except `build-win-native*` which
require a locally installed mingw-w64). macOS builds use **osxcross** to
provide the Apple SDK and toolchain inside the Linux-based Docker image.
```bash
# Build Linux .so via Docker (x86_64)
make build-linux
# Build Linux .so via Docker (ARM64)
make build-linux-arm64
# Build macOS .dylib via Docker using osxcross (Intel)
make build-mac-x64
# Build macOS .dylib via Docker using osxcross (Apple Silicon)
make build-mac
# Build Windows DLL via Docker (x86_64)
make build-win
# Build Windows DLL natively (x86_64, requires mingw-w64)
make build-win-native
# Build Windows DLL natively in release mode
make build-win-native-release
```
> **Note:** Windows ARM64 and Linux ARM64 builds are also available as
> [pre-built binaries](#pre-built-binaries) from GitHub Releases, built natively
> on GitHub Actions runners.
Or directly with Cargo:
```bash
cargo build --release
cargo build --lib # shared library only
```
## Data Model
```
CardData
โโโ personal: Personal
โ โโโ cid โ 13-digit citizen ID
โ โโโ name โ Full name in Thai (with prefix, first, middle, last)
โ โโโ name_en โ Full name in English
โ โโโ dob โ Date of birth (YYYY-MM-DD)
โ โโโ gender โ M or F
โ โโโ card_issuer โ Issuing authority
โ โโโ issue_date โ Card issue date (YYYY-MM-DD)
โ โโโ expire_date โ Card expiry date (YYYY-MM-DD)
โ โโโ address โ Registered address (parsed into components)
โ โโโ face_image โ Face photo as base64 JPEG
โโโ card: Card
โ โโโ laser_id โ Laser-engraved serial number
โโโ nhso: Nhso
โโโ main_inscl โ Main insurance scheme
โโโ sub_inscl โ Sub insurance scheme
โโโ main_hospital โ Primary hospital
โโโ sub_hospital โ Secondary hospital
โโโ paid_type โ Payment type
โโโ issue_date โ NHSO coverage start date
โโโ expire_date โ NHSO coverage end date
โโโ update_date โ Last update date
โโโ change_hospital_amount โ Hospital change count
```
## Project Structure
```
โโโ Cargo.toml
โโโ Makefile
โโโ Dockerfile.build โ Cross-compilation Docker image (osxcross)
โโโ src/
โ โโโ lib.rs โ Main API (SmartCard, start_daemon)
โ โโโ ffi.rs โ C-compatible FFI exports
โ โโโ model.rs โ Data types & parsing helpers
โ โโโ apdu.rs โ APDU command constants
โ โโโ reader.rs โ Low-level PC/SC operations
โ โโโ personal.rs โ Personal data reader
โ โโโ nhso.rs โ NHSO data reader
โ โโโ laser.rs โ Laser ID reader
โ โโโ options.rs โ Configuration options
โโโ examples/
โโโ rust_usage.rs โ Rust usage example
โโโ c_usage.c โ C usage example
โโโ cpp_usage.cpp โ C++ usage example
โโโ go_usage.go โ Go usage example
โโโ java_usage.java โ Java usage example
โโโ kotlin_usage.kt โ Kotlin usage example
โโโ js_usage.js โ JavaScript usage example
โโโ python_usage.py โ Python usage example
โโโ ruby_usage.rb โ Ruby usage example
```
## References
- [Thai National ID Card APDU Specification](https://github.com/chakphanu/ThaiNationalIDCard/blob/master/APDU.md)
- [go-thai-smartcard NHSO APDU Implementation](https://github.com/somprasongd/go-thai-smartcard/blob/main/pkg/apdu/nhso.go)
## License
Licensed under either of:
- MIT license ([LICENSE-MIT](LICENSE-MIT))
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE))
at your option.