Created
August 25, 2018 16:56
-
-
Save o0Ignition0o/786ab27160df2abfc336055c7d1015ef to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![crate_type = "staticlib"] | |
//#![feature(test)] | |
//extern crate test; | |
use std::slice; | |
use std::str; | |
#[inline] | |
fn try_apply_digit(current_octet: u8, digit_to_apply: u8) -> Option<u8> { | |
current_octet.checked_mul(10)?.checked_add(digit_to_apply) | |
} | |
pub fn is_valid_ipv4_addr<'a>(addr: &'a [u8]) -> bool { | |
let mut current_octet: Option<u8> = None; | |
let mut dots: u8 = 0; | |
for c in addr { | |
let c = *c as char; | |
match c { | |
'.' => { | |
match current_octet { | |
None => { | |
// starting an octet with a . is not allowed | |
return false; | |
} | |
Some(_) => { | |
dots = dots + 1; | |
current_octet = None; | |
} | |
} | |
} | |
// The caracter is not a digit | |
no_digit if no_digit.to_digit(10).is_none() => { | |
return false; | |
} | |
digit => { | |
match current_octet { | |
None => { | |
// Unwrap is sound because it has been checked in the previous arm | |
current_octet = Some(digit.to_digit(10).unwrap() as u8); | |
} | |
Some(octet) => { | |
if let Some(0) = current_octet { | |
// Leading 0 is not allowed | |
return false; | |
} | |
if let Some(applied) = | |
try_apply_digit(octet, digit.to_digit(10).unwrap() as u8) | |
{ | |
current_octet = Some(applied); | |
} else { | |
// Multiplication or Addition overflowed | |
return false; | |
} | |
} | |
} | |
} | |
} | |
} | |
dots == 3 && current_octet.is_some() | |
} | |
#[inline] | |
fn try_apply_opt_digit(current_octet: Option<u8>, digit_to_apply: u8) -> Option<u8> { | |
if current_octet.is_none() { | |
return Some(digit_to_apply); | |
} | |
current_octet.unwrap().checked_mul(10)?.checked_add(digit_to_apply) | |
} | |
#[inline] | |
fn try_parse_digit<'a>(digit: &'a [u8]) -> Option<u8> { | |
let mut res: Option<u8> = None; | |
for d in digit { | |
if let Some(applied) = try_apply_opt_digit(res, *d) { | |
res = Some(applied); | |
} else { | |
return None; | |
} | |
} | |
res | |
} | |
pub fn is_valid_ipv4_addr_readable<'a>(addr: &'a [u8]) -> bool { | |
let mut n = 0; | |
let dot = '.' as u8; | |
for digit in addr.split(&dot) { | |
n += 1; | |
if n > 4 { | |
return false; | |
} | |
// Starting an octet with a . is not allowed. | |
if digit.len() == 0 { | |
return false; | |
} | |
if let Some(_) = try_parse_digit(digit) { | |
continue; | |
} else { | |
// Parsed garbage, out-of-range, or otherwise invalid number. | |
return false; | |
} | |
} | |
n == 4 | |
} | |
#[no_mangle] | |
#[allow(non_snake_case)] | |
pub extern "C" fn rust_net_is_valid_ipv4_addr<'a>(addr: &'a u8, addrLen: i32) -> bool { | |
let address = unsafe { slice::from_raw_parts(addr, addrLen as usize) }; | |
is_valid_ipv4_addr(address) | |
} | |
#[no_mangle] | |
#[allow(non_snake_case)] | |
pub extern "C" fn rust_net_is_valid_ipv4_addr_readable<'a>(addr: &'a u8, addrLen: i32) -> bool { | |
let address = unsafe { slice::from_raw_parts(addr, addrLen as usize) }; | |
is_valid_ipv4_addr_readable(address) | |
} | |
/* | |
#[cfg(test)] | |
mod tests { | |
use is_valid_ipv4_addr; | |
use is_valid_ipv4_addr_readable; | |
use test::{black_box, Bencher}; | |
#[bench] | |
fn bench_is_valid_ipv4_address_full_digits_more_readable(bench: &mut Bencher) { | |
let ip: &str = "192.168.101.117"; | |
bench.iter(|| black_box(is_valid_ipv4_addr_readable(ip))); | |
} | |
#[bench] | |
fn bench_is_valid_ipv4_address_full_digits(bench: &mut Bencher) { | |
let ip: [u8; 15] = [ | |
'1' as u8, '9' as u8, '2' as u8, '.' as u8, '1' as u8, '6' as u8, '8' as u8, '.' as u8, | |
'1' as u8, '0' as u8, '1' as u8, '.' as u8, '1' as u8, '1' as u8, '7' as u8, | |
]; | |
bench.iter(|| black_box(is_valid_ipv4_addr(&ip))); | |
} | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment