前言
本文是基于rust,对16进制、32位浮点数之间的互相转换的一个简单示例。
环境配置
系统:windows
平台:visual studio code
语言:rust
库:hex
关键依赖
hex="0.4.3"
对于字符串与16进制之间的互相转换,我们使用hex这个crate。所以需要添加hex依赖,在toml文件中手动添加,如上,或者使用cargo添加:
cargo add hex
也可以指定版本:
cargo add hex@0.4.3
数字字符串转字节数组
为了方便管理,我们可以新建一个rust文件,命名为hexconvert.rs。然后我们在其中编写功能函数,首先是string_to_hex:
///
/// 字符串转16进制
///
/// 例:'01030002' -> [0x01,0x03,0x00,0x02]
pub fn string_to_hex(s:String) -> Vec<u8> {let input_re=hex::decode(s);if let Ok(input_hex) = input_re{return input_hex} else {return vec![]}
}
hex的函数decode的作用是解码字符串,将对应的数字字符串解码为字节数组,字节数组就是我们所需要的原始数据,可以显示为各种进制的数值,当然也包括16进制。
字节数组转32位浮点数
rust中有自带的处理数值的函数,对于32位浮点数即f32数值类型,可以使用from_be_bytes或者from_le_bytes来从字节数组转换。
///
/// 16进制转32位浮点数
///
/// Example 1:
///
/// [0x41,0x48,0x00,0x00] -> 12.5(mode is "big endian")
///
/// [0x00,0x00,0x48,0x41] -> 12.5(mode is "little endian")
///
/// Example 2:
///
/// [0x41,0x48,0x00,0x00,...] -> ???(长度判断)
///
///
pub fn hex_to_float_frombytes<T: AsRef<[u8]>>(hex: T, mode: Option<&str>) -> Option<f32> {let bytes = hex.as_ref();if bytes.len() == 4 {let mut array = [0u8; 4];array.copy_from_slice(bytes);match mode.unwrap_or("big") {"big" => Some(f32::from_be_bytes(array)),"little" => Some(f32::from_le_bytes(array)),_ => {Some(f32::from_ne_bytes(array))}}} else {println!("err:数组长度异常");None}
}
在上面的函数中,我们对传入的字节数组进行了简单判断,因为32位浮点数,长度是4个字节,所以字节长度如果不对,那么转换的数值显然也是错误的。另外,不同的终端控制器或者发送设备,其字节端序也不一定一样,有大端和小端之分,即big endian和little endian,也就是be和le。
所以,我们还添加了一个mode参数,用于判断端序。
浮点数转字符串
将一个浮点型数值转为等值的字符串或者16进制字符串,我们可以使用hex的encode函数。
///
/// 32位浮点数转字符串
///
/// 例:12.5 -> "12.5"(to_hex is false)
///
/// 例:12.5 -> "0x41,0x48,0x00,0x00"(to_hex is true)
#[allow(unused)]
pub fn float_to_string(f:f32,mode:Option<&str>,to_hex:bool) -> String {let mut s:String=String::new();if to_hex == false {s=format!("{}",f)} else {match mode.unwrap_or("big") {"big" => {let hex=hex::encode(f.to_be_bytes());s=format!("{}",hex)},"little" => {let hex=hex::encode(f.to_le_bytes());s=format!("{}",hex)},_ => {let hex=hex::encode(f.to_ne_bytes());s=format!("{}",hex)}}}return s
}
此处我们增加了to_hex来选择是直接转为等值字符还是转为等值16进制字符。
下面是一个实例演示,我们将通过终端输入一个字符串:00004841,这是小端序的浮点数:12.5。
我们使用小端序解码,然后是大端序再转会字符串,看看效果:
rust字符串与字节数组转换演示