Я не могу получить исходные байты из объединенной байтовой строки в Rust

Я преобразовал файл в байты и получил vec/массив

[68, 114, 97, 109, 97, 116, 105, 99, 32, 115, 97, 120, 97, 112, 104, 111, 110, 101, 32, 112, 108, 97, 121, 115, 32, 73, 78, 32, 84, 72, 69, 32, 68, 73, 83, 84, 65, 78, 67, 69]

Когда я объединил это, у меня получился номер 4920555689216983877.

Теперь моя проблема заключается в том, что всякий раз, когда я пытаюсь преобразовать это число обратно в байты, у меня остаются только 8 конечных байтов.

Я тестировал это как с крейтом Rust по умолчанию, так и с крейтом BigInt, и ни один из них меня не удовлетворил:

use num_bigint::{BigUint, ToBigUint};
use num_traits::{Zero, One, ToPrimitive, ToBytes, Num};

fn main() {
    let the_u8: u128 = 4920555689216983877;
    let bigone = (4920555689216983877 as u128).to_biguint().expect("might fail");
    let the_u8bytes: [u8;16] = the_u8.to_be_bytes(); //Using a simple array for demonstrated purposes
    let bigonebytes: Vec<u8> = bigone.to_be_bytes();
    println!("Bytes of base u8: {:?}", the_u8bytes);
    println!("Base of BigInt: {:?}", bigonebytes);
}

[dependencies]
num-bigint = "0.4.4"
num-traits = "0.2.18"

По какой-то причине я не могу собрать исходный файл, который является неотъемлемой частью моей программы, но мне кажется, что я выполнил все логические шаги по обратному проектированию этого упрощенного процесса. Может ли кто-нибудь объяснить, что именно происходит не так, и помочь мне сформулировать стратегию противодействия этому?

Раньше я задавал аналогичный вопрос, но у меня не было лучшего минимального воспроизводимого примера, теперь, когда я попытался создать отдельный проект, чтобы попытаться воспроизвести свои проблемы, я столкнулся с аналогичным затруднительным положением.

Это функция, которую я использовал для создания единственного числа для представления всех байтов в десятичном формате:

fn concatenate_bytes(bytes: &[u8]) -> BigUint {
    
    println!("Bytes: {:?}", bytes);
    let mut result = 0;

    let mut raw_dog = bytes.as_ptr();
    for _ in bytes.iter() {
        

        unsafe{ 
            result = (result << 8) | (*raw_dog as u64);
            raw_dog = raw_dog.offset(1);
        }
    }
    println!("Result: {}", result);
    result.to_biguint().expect("Failed to create uint")
    //Is actually valid ??? ^
}

Многие комментарии были сделаны лично для меня, но я понимаю, что они не особенно полезны для вас.

I ended up with the number 4920555689216983877 ... вы уверены, что тип данных — число?
jsotola 02.05.2024 06:32
4920555689216983877 для его представления требуется всего 8 байт, поэтому размещение его в типе u128 или bigint не приведет к созданию байтов, если их нет.
kmdreko 02.05.2024 06:33

«Когда я соединил это, я получил число…» — вам придется подробнее объяснить, как это работает, потому что оказывается, что, несмотря на то, что вы получили это число, оно представляет только последние восемь байтов ваших данных.

kmdreko 02.05.2024 06:33

@kmdreko Я использовал функцию, которая объединяла все байты в единственное целое число, а затем использовал хэш-карту для преобразования этого единственного целого числа в другую базу. Я знаю, что я преобразовал число из отдельной базы обратно в исходную базу, как только я перевернул хэш-карту, повторил процесс еще раз и в итоге получил то же число, с которым я исходил.

Thetrue kingofwaffles 02.05.2024 06:39

Почему люди используют unsafe там, где это совершенно не нужно?

Chayim Friedman 02.05.2024 08:43

@ChayimFriedman, моя идея говорит, что это небезопасно, поэтому я использовал небезопасный блок, Rust Analyzer сказал мне, что это так.

Thetrue kingofwaffles 02.05.2024 23:00

Ну да, но вы можете просто использовать (безопасный) итератор. И этим вам даже удалось вызвать UB. Держитесь подальше от небезопасных, как новичок.

Chayim Friedman 02.05.2024 23:01

Я бы, честно говоря, не хотел сразу переходить к переполнению стека, поэтому использовал Chat Gpt, чтобы помочь себе, но когда я дошел до определенного момента, я попал в ловушку кода, который написал ранее. Я не осознавал, что нажимал байты, поэтому осталось только 8 байтов. Я некоторое время возился с Rust и делал это небезопасно, когда некоторое время назад создавал простое ядро, но я предположил, что моя первоначальная ошибка заключалась в записи байтов, а не в том, как я их объединял. Я заметил, что моя программа работала только с меньшими значениями, но теперь я вижу, что есть безопасный итератор, который я мог бы использовать в BigUInt.

Thetrue kingofwaffles 02.05.2024 23:05

Первоначально я использовал обычный u32-u128, прежде чем перешел к использованию больших целых чисел и num_traits.

Thetrue kingofwaffles 02.05.2024 23:07
Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
2
9
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша функция concatenate_bytes теряет информацию. Переменная result является u64, что означает, что она будет содержать только до 8 байт информации. Если вы поместите в него байт, а затем << 8 еще восемь раз, то этот байт «вытолкнется» из результата. Таким образом, result в конечном итоге отражает только последние 8 байтов.

Если вы используете функцию, которая сохраняет все байты в BigUint, например from_bytes_be, то из исходных данных вы получите такое число:

use num_bigint::BigUint;

let bytes = &[68, 114, 97, 109, 97, 116, 105, 99, 32, 115, 97, 120, 97, 112, 104, 111, 110, 101, 32, 112, 108, 97, 121, 115, 32, 73, 78, 32, 84, 72, 69, 32, 68, 73, 83, 84, 65, 78, 67, 69];
let biguint = BigUint::from_bytes_be(bytes);
println!("{biguint}");
571099513965487418103312191225646346334778926396615879607986731592501905638024494155407303787333

Загрузка этого числа как BigUint и использование to_bytes_be вернет исходные байты.

Спасибо, я не осознавал, что активно терял информацию, не конвертируя файл в бигуинт. Я бы использовал его позже в своей программе при объединении байтов, но теперь я вижу, что при объединении байтов я теряю информацию. Когда сегодня я пересмотрю свою программу, я посмотрю, работает ли эта версия лучше.

Thetrue kingofwaffles 02.05.2024 15:11

Я также хотел бы сказать спасибо за то, что вы помогли мне дважды подряд.

Thetrue kingofwaffles 02.05.2024 15:12

Другие вопросы по теме