#rust #type-conversion #bit
#Ржавчина #тип-преобразование #бит
Вопрос:
Мне нужно преобразовать количество битов, которое переходит из нотации CIDR в фактическую маску подсети. Например 192.168.0.1/30
. Здесь 30
— количество битов, которые установлены в сетевой маске (в этом примере — 255.255.255.252
). Я делаю это путем преобразования количества битов в фактическую строку, а затем использую u32::from_str_radix
метод для получения фактического числа (которое я могу использовать для Ipv4Addr
struct, поскольку в нем реализован From<u32>
признак). Вот код:
let bit_length = 30
let bits = format!("{:0<32}", "1".repeat(bit_length as usize));
net_mask = IpAddr::V4(u32::from_str_radix(bits.as_str().into(), 2)?.into());
Мне интересно, есть ли другой способ, возможно, более элегантный, преобразовать количество битов в целое число, когда мы знаем размер целевого числа (32-разрядное в этом примере)? Может быть, какая-то магия бита, о которой я не знаю?
Ответ №1:
Если вы хотите, чтобы первые 30 битов были равны 1, это означает, что последние 2 бита должны быть равны 0. Итак, мы можем получить число, где каждый бит равен 1, взяв побитовое значение not из 0, затем сдвинув его влево на два бита, чтобы получить два 0.
let bit_length = 30;
let bits: u32 = (!0) << (32 - bit_length);
let net_mask = IpAddr::V4(bits.into());
println!("{:?}", net_mask);
Комментарии:
1. Это именно то, что мне нужно, большое вам спасибо @Aplet123!