From 6de37990df357010890f2be62f324925a7430fd3 Mon Sep 17 00:00:00 2001 From: gongzhengyang Date: Mon, 19 Dec 2022 15:49:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E6=88=90IP=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- binding/rust/src/lib.rs | 62 +++++++++++++++++++++------------------- binding/rust/src/main.rs | 5 +++- 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/binding/rust/src/lib.rs b/binding/rust/src/lib.rs index 5896672..12762a0 100644 --- a/binding/rust/src/lib.rs +++ b/binding/rust/src/lib.rs @@ -1,11 +1,9 @@ use std::fs::File; -use std::net::{IpAddr, Ipv4Addr}; -use std::io::{Read, Bytes}; - -fn main() {} +use std::io::Read; +use std::net::Ipv4Addr; const HEADER_INFO_LENGTH: u32 = 256; -const VECTOR_INDEX_ROWS: u32 = 256; +// const VECTOR_INDEX_ROWS: u32 = 256; const VECTOR_INDEX_COLS: u32 = 256; const VECTOR_INDEX_SIZE: u32 = 8; const SEGMENT_INDEX_SIZE: usize = 14; @@ -24,24 +22,25 @@ impl Searcher { pub fn search_by_ip(&self, ip: &'static str) -> Result> { let ip = ip.parse::().unwrap_or_else(|_| { - let ip = ip.parse::().expect("ip is not a valid ip or valid int"); + let ip = ip + .parse::() + .expect("ip is not a valid ip or valid int"); Ipv4Addr::from(ip) }); - println!("{:?}", ip); let ip = u32::from(ip); let il0 = (ip >> 24) & 0xFF; let il1 = (ip >> 16) & 0xFF; - let idx = VECTOR_INDEX_SIZE * (il0 * VECTOR_INDEX_SIZE * VECTOR_INDEX_COLS + il1); + let idx = VECTOR_INDEX_SIZE * (il0 * VECTOR_INDEX_COLS + il1); - let start_ptr = get_u32(&self.buffer, (HEADER_INFO_LENGTH + idx) as usize); - let end_ptr = get_u32(&self.buffer, (HEADER_INFO_LENGTH + idx+4) as usize); - - let mut left: usize= 0; - let mut right: usize = ((end_ptr - start_ptr) as usize )/SEGMENT_INDEX_SIZE; - while left < right { + let start_point = (HEADER_INFO_LENGTH + idx) as usize; + let start_ptr = get_u32(&self.buffer, start_point); + let end_ptr = get_u32(&self.buffer, start_point + 4); + let mut left: usize = 0; + let mut right: usize = ((end_ptr - start_ptr) as usize) / SEGMENT_INDEX_SIZE; + while left <= right { let mid = (left + right) >> 1; - let offset = start_ptr as usize + mid * SEGMENT_INDEX_SIZE; + let offset = (start_ptr as usize) + mid * SEGMENT_INDEX_SIZE; let buffer_ip_value = self.buffer_value(offset, SEGMENT_INDEX_SIZE); let start_ip = get_u32(buffer_ip_value, 0); if ip < start_ip { @@ -49,28 +48,32 @@ impl Searcher { } else if ip > get_u32(buffer_ip_value, 4) { left = mid + 1; } else { - let length = (self.buffer[offset] as usize & 0x000000FF) | (self.buffer[offset + 1] as usize & 0x0000FF00); - let offset = get_u32(&self.buffer, 10); - let result = self.buffer_value(offset as usize, length as usize).iter().map(|x| x.to_owned()).collect::>(); + let length = (buffer_ip_value[8] as usize & 0x000000FF) + | (buffer_ip_value[9] as usize & 0x0000FF00); + + let offset = get_u32(&buffer_ip_value, 10); + let result = self + .buffer_value(offset as usize, length) + .iter() + .map(|x| x.to_owned()) + .collect::>(); return Ok(String::from_utf8(result)?); } } Err("not matched".into()) - } pub fn buffer_value(&self, offset: usize, length: usize) -> &[u8] { - &self.buffer[offset..offset+length] + &self.buffer[offset..offset + length] } } fn get_u32(bytes: &[u8], offset: usize) -> u32 { - let offset = offset as usize; - let tmp = (bytes[offset] as i64) & 0x000000FF - | ((bytes[offset + 1] as i64) << 8) & 0x0000FF00 - | ((bytes[offset + 2] as i64) << 16) & 0x00FF0000 - | ((bytes[offset + 3] as i64) << 24) & 0xFF000000; - tmp as u32 + let result = (bytes[offset] as u32) & 0x000000FF + | ((bytes[offset + 1] as u32) << 8) & 0x0000FF00 + | ((bytes[offset + 2] as u32) << 16) & 0x00FF0000 + | ((bytes[offset + 3] as u32) << 24) & 0xFF000000; + result } #[cfg(test)] @@ -81,8 +84,9 @@ mod tests { fn test_search_by_ip() { let filepath = "../../data/ip2region.xdb"; let searcher = Searcher::new(filepath).expect("load file error"); - let result = searcher.search_by_ip("1.0.0.0"); + let result = searcher.search_by_ip("2.0.0.0"); println!("{:?}", result); - } -} \ No newline at end of file +} + +fn main() {} diff --git a/binding/rust/src/main.rs b/binding/rust/src/main.rs index 7605184..86682d1 100644 --- a/binding/rust/src/main.rs +++ b/binding/rust/src/main.rs @@ -1,5 +1,8 @@ mod lib; fn main() { - println!("Hello, world!"); + let filepath = "../../data/ip2region.xdb"; + let searcher = lib::Searcher::new(filepath).expect("load file error"); + let result = searcher.search_by_ip("1.2.165.128"); + println!("{:?}", result); }