Раст в панике: попытка умножения с переполнением
Я пытаюсь составить полином для алгоритма шифрования AES.
fn new() предназначен для построения бит-векторного представления числа x.
любого поля galois_field, чтобы использовать его для сложения и умножения
Extension_field (из алгоритма AES).
#[derive(Debug)]
struct polynomial(Vec<u8>);
impl polynomial {
fn new(mut x: i16) -> Self {
println!("polynomial::new() --> Start");
let mut poly: Vec<u8> = Vec::new();
for e in 0..16 {
poly.push(0);
}
for e in (0..16).rev() {
println!("polynomial::new() :: loop :: --> In ");
if x > 0 {
if x - 2_i16.pow(e) >= 2_i16.pow(e - 1) || x - 2_i16.pow(e) == 0 {
x -= 2_i16.pow(e);
poly[e as usize] = 1;
}
} else {
if x - 1 == 0 {
poly[e as usize] = 1;
println!("x : {x}");
println!("polynomial : {poly:#?}");
}
}
}
println!("polynomial::new() --> End");
return Self(poly);
}
}
fn main() {
let x = polynomial::new(7);
let y = polynomial::new(41);
let z = polynomial::add(x, y);
println!("z : {z:#?}");
}
Когда я запускаю код, я знаю, что ошибка возникает во втором println! макросе, но я не знаю, в каком if операторе. Это вывод во время выполнения:
polynomial::new() --> Start
polynomial::new() :: loop :: --> In
thread 'main' panicked at /usr/src/debug/rust/rustc-1.78.0-src/library/core/src/num/mod.rs:324:5:
attempt to multiply with overflow
Я понятия не имею, почему это происходит. Хотел поставить RUST_BACKTRACE = 1 но не знаю как.
Подсказка: каков результат 2**16? Какое самое большое число i16 может храниться?
добавляя к приведенному выше предложению, имейте в виду, что если e равно 0, то 2_i16 будет 2_i16(-1), что должно равняться 0,5. следовательно, int не может с этим справиться, так существует ли тип данных, который может с этим справиться?
@ChayimFriedman, я понимаю, что вы имеете в виду, но я не понимаю, почему максимальный бит i16 равен «2_i16.pow(14)» вместо «2_i16.pow(15)»
@Titoot, спасибо за указание, правильное if должно быть «if e > 0».
1 бит на знак, еще 1 бит на ведущую 1, затем остается 14 бит.

На самом деле решение было очень простым. Мне нужно было только изменить примитивные значения на i32 и не позволять им переполнять максимальное значение u16.
fn new(mut x: i32) -> Result<Self, ()> {
if x > std::u16::MAX.into() {
println!("x must be equal or lower than u16::MAX");
return Err(());
}
let mut poly: Vec<u8> = Vec::new();
for e in 0..16 {
poly.push(0);
}
for e in (0..16).rev() {
if x - 2_i32.pow(e) > -1 {
x -= 2_i32.pow(e);
poly[e as usize] = 1;
}
}
Просто в командной строке RUST_BACKTRACE=1 запустите груз или какой бы двоичный файл вы ни запускали, приятель. Что будет делать. Вы используете груз? Однако я не вижу функции добавления. в полиномическом следует использовать заглавную букву (Полиномиальный). Молодцы с AES!