| Crates.io | xdb-parse |
| lib.rs | xdb-parse |
| version | 0.1.0 |
| created_at | 2025-09-23 06:31:00.009766+00 |
| updated_at | 2025-09-23 06:31:00.009766+00 |
| description | A parser to xdb files like ip2region |
| homepage | https://github.com/RuntimeBroker/xdb_parse |
| repository | https://github.com/RuntimeBroker/xdb_parse |
| max_upload_size | |
| id | 1851055 |
| size | 47,750 |
A parser to xdb files like ip2region A high-performance Rust library for parsing and querying IP database files (xdb format) like ip2region. Supports both IPv4 and IPv6 address lookup with efficient binary search algorithms.
Add this to your Cargo.toml:
[dependencies]
xdb-parse = "0.1.0"
use xdb_parse::utils::{load_file, search_ip};
use anyhow::Result;
fn main() -> Result<()> {
// Load the IP database file
let path = "./assets/ip2region_v4.xdb";
let data = load_file(path.into())?;
// Search for an IP address
let result = search_ip("73.24.63.66", &data)?;
println!("IP location: {}", result);
Ok(())
}
use xdb_parse::utils::{load_file, search_ip};
use anyhow::Result;
fn main() -> Result<()> {
// Load IPv6 database
let path = "./assets/ip2region_v6.xdb";
let data = load_file(path.into())?;
// Search for IPv6 address
let result = search_ip("2001:0db8:85a3:0000:0000:8a2e:0370:7334", &data)?;
println!("IPv6 location: {}", result);
Ok(())
}
See examples/search_ip.rs:
use std::time::Instant;
use anyhow::Result;
use xdb_parse::utils::{load_file, search_ip};
fn main() -> Result<()> {
let start = Instant::now();
let path = "./assets/ip2region_v4.xdb";
let data = load_file(path.into())?;
let ret = search_ip("73.24.63.66", &data)?;
let time = start.elapsed();
println!("Search time: {:?} - Result: {}", time, ret);
Ok(())
}
The library is designed for thread-safe concurrent usage:
use std::{sync::Arc, thread};
use xdb_parse::utils::{load_file, search_ip};
use anyhow::Result;
fn main() -> Result<()> {
let path = "./assets/ip2region_v6.xdb";
let data = Arc::new(load_file(path.into())?);
let data_clone = Arc::clone(&data);
let handle = thread::spawn(move || {
let result = search_ip("2408:8352:da10:1ad:c283:c9ff:fec6:4046", &data_clone).unwrap();
println!("Thread result: {}", result);
});
// Main thread can also query
let result = search_ip("2408:8352:da10:1ad:c283:c9ff:fec6:4046", &data)?;
println!("Main thread result: {}", result);
handle.join().unwrap();
Ok(())
}
See benches/search.rs for performance testing:
use criterion::{Criterion, criterion_group, criterion_main};
use xdb_parse::utils::{load_file, search_ip};
fn search_benchmark(c: &mut Criterion) {
c.bench_function("ipv4_search", |b| {
let path = "./assets/ip2region_v4.xdb";
let data = load_file(path.into()).unwrap();
b.iter(|| {
search_ip("73.24.63.66", &data).unwrap();
})
});
}
criterion_group!(benches, search_benchmark);
criterion_main!(benches);
load_file(path: PathBuf) -> Result<Vec<u8>, XdbError>Loads an xdb database file into memory.
Parameters:
path: Path to the xdb fileReturns: Byte vector containing the database data
search_ip(ip: &str, data: &[u8]) -> Result<String, XdbError>Searches for an IP address in the loaded database.
Parameters:
ip: IP address to search (supports multiple formats)data: Database data loaded by load_fileReturns: Location information as string
The library accepts IP addresses in multiple formats:
// Standard IPv4 format
search_ip("192.168.1.1", &data)?;
// Standard IPv6 format
search_ip("2001:0db8:85a3::0370:7334", &data)?;
// Numeric format (IPv4)
search_ip("3232235777", &data)?; // Equivalent to 192.168.1.1
// Numeric format (IPv6)
search_ip("42540766411282592856903984951653826560", &data)?;
The library supports the xdb format used by ip2region:
┌─────────────────┐
│ Header │ 256 bytes
├─────────────────┤
│ Vector Index │ 256×256×8 bytes
├─────────────────┤
│ Segment Data │ Variable length
└─────────────────┘
The library uses an optimized binary search algorithm:
The library uses thiserror for comprehensive error handling:
use xdb_parse::error::XdbError;
match search_ip("invalid_ip", &data) {
Ok(result) => println!("Location: {}", result),
Err(XdbError::InvalidIP(msg)) => println!("Invalid IP: {}", msg),
Err(e) => println!("Error: {}", e),
}
To run the provided examples:
# Run the basic search example
cargo run --example search_ip
# Run benchmarks
cargo bench
# Run tests
cargo test
This project is licensed under the same terms as Rust itself.
Contributions are welcome! Please feel free to submit issues and pull requests.