Is there a readily available way to convert ip addresses (both v4 and v6) from binary to text form in Rust (an equivalent to inet_ntop)?
Examples:
"3701A8C0" converts to "55.1.168.192","20010db8000000000000000000000001" converts to "2001:db8::1".inet_ntop takes as input a struct in_addr* or a struct in6_addr*. The direct equivalent of those structs in Rust are Ipv4Addr and Ipv6Addr, both of which implement the Display trait and can therefore be formatted easily to text or printed:
let addr = Ipv4Addr::from (0x3701A8C0);
assert_eq!(format!("{}", addr), String::from ("55.1.168.192"));
println!("{}", addr);
AFAIK, there is not a direct conversion, but you can do that with from_str_radix, and then with the conversion of an ip from a numeric type:
use std::{
error::Error,
io,
net::{IpAddr, Ipv4Addr, Ipv6Addr},
str::FromStr,
};
fn convert(s: &str) -> io::Result<IpAddr> {
if let Ok(u) = u32::from_str_radix(s, 16) {
Ok(Ipv4Addr::from(u).into())
} else if let Ok(u) = u128::from_str_radix(s, 16) {
Ok(Ipv6Addr::from(u).into())
} else {
Err(io::Error::new(io::ErrorKind::InvalidData, "Invalid input"))
}
}
fn main() -> Result<(), Box<dyn Error>> {
let ip = convert("3701A8C0")?;
assert_eq!(ip, IpAddr::from_str("55.1.168.192")?);
let ip = convert("20010db8000000000000000000000001")?;
assert_eq!(ip, IpAddr::from_str("2001:db8::1")?);
Ok(())
}
If you already know that it is, for example, and IPV4, this is a one-liner:
use std::{
error::Error,
net::{IpAddr, Ipv4Addr},
str::FromStr,
};
fn main() -> Result<(), Box<dyn Error>> {
let ip = u32::from_str_radix("3701A8C0", 16).map(Ipv4Addr::from)?;
assert_eq!(ip, IpAddr::from_str("55.1.168.192")?);
Ok(())
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With