Convert string to u128

I tested somethings with follow lines but is does not working and I think closest solution would be unsafe but I do not know how can I use it(although I worked on const and static and struct but it was doesn't work) I will need a pure u128

pub fn u128_bytes (u: &u128) -> [u8; 16] {
    [
        (u >> 8 * 0x0) as u8,
        (u >> 8 * 0x1) as u8,
        (u >> 8 * 0x2) as u8,
        (u >> 8 * 0x3) as u8,

        (u >> 8 * 0x4) as u8,
        (u >> 8 * 0x5) as u8,
        (u >> 8 * 0x6) as u8,
        (u >> 8 * 0x7) as u8,

        (u >> 8 * 0x8) as u8,
        (u >> 8 * 0x9) as u8,
        (u >> 8 * 0xa) as u8,
        (u >> 8 * 0xb) as u8,

        (u >> 8 * 0xc) as u8,
        (u >> 8 * 0xd) as u8,
        (u >> 8 * 0xe) as u8,
        (u >> 8 * 0xf) as u8,
    ]
}

dirty code:

    let difficulty = 0x0fffffffffffffffffffffffffffffff;        
    //write!("{:X}","0x00000000fffffffffffffffffffffff");
    set_var("DIFFICULTY", "0x000fffffffffffffffffffffffffffff");
    let mut d=var_ret_difficulty("0x000fffffffffffffffffffffffffffff");
    //library_utils::ustrtou128::safe_string_to_u128u(&mut difficulty);
    let mut fbuffer: Vec<u8> = vec![];
    let mut buffer= std::io::BufReader::new(d.as_bytes());
    if buffer.read_vectored(&mut fbuffer).is_err() {
        println!("Error checking is working");
      }

    println!("{:0b}",&buf);


    // let difficulty=difficulty_bytes_as_u128(&buf);  
    // let hexa = u128::from(difficulty) << 64;
    // println!("{hexa}");
struct Difficulty{
    Num:String
}
impl fmt::UpperHex for Difficulty {
    fn fmt(mut self: &Difficulty, f: &mut fmt::Formatter) -> fmt::Result {
        let bytes = self.Num.as_bytes().to_vec();    
        let  difficulty=difficulty_bytes_as_u128(&bytes);  
         
    //  unsafe {
    //     //std::mem::transmute(NumUu as u128);
    //     NumUu+=difficulty;
    //    // NumUu=*(difficulty as *const u128)
    // };

        let hexa = u128::from(difficulty) << 64;
        write!(f, "{:X}", hexa)
    }
}

It looks like you might be looking for https://doc.rust-lang.org/std/primitive.u128.html#method.to_le_bytes?

5 Likes

I will insist to get input difficulty string from user so I can use .

let bytes = 0x12345678901234567890123456789012u128.to_be_bytes();
assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12]);

Thanks

And this code is not either fix it too.

let difficulty = e.trim().parse::<u128>()).as_ref().unwrap();     

is there anyway by using Duration or Ip crates?
What about unsafe?

Try this:

let difficulty: u128 = e.trim().parse().unwrap();
1 Like

No it dose not working it changed value for exampe 0xffff... to 0x6666

Do you mean that the user will input the value in hexadecimal, and you want to get u128 from that? In this case, you probably want to process the string manually - check that it has 0x at the beginning, then process each consequent character, either manually or with to_digit, and finally combine them into one number (possibly with the intermediate [u8; 16] and from_be_bytes).

3 Likes

Yah after responses of stackoverflow I am going to use this manual strategy. Thanks

This would actually be sped up and simpler by using a parse function with a radix argument. Each integral type has one, here's u128's.

4 Likes

I switched to nightly but it did not work.

installed toolchains
--------------------

stable-x86_64-unknown-linux-gnu
nightly-2018-10-05-x86_64-unknown-linux-gnu
nightly-2020-07-10-x86_64-unknown-linux-gnu
nightly-2020-10-01-x86_64-unknown-linux-gnu
nightly-2020-10-06-x86_64-unknown-linux-gnu
nightly-2021-08-30-x86_64-unknown-linux-gnu
nightly-2021-08-31-x86_64-unknown-linux-gnu
nightly-x86_64-unknown-linux-gnu (default)

installed targets for active toolchain
--------------------------------------

wasm32-unknown-unknown
x86_64-unknown-linux-gnu

active toolchain
----------------

nightly-x86_64-unknown-linux-gnu (overridden by '/mnt/home/rust-scratche-blockchain/rust-toolchain.toml')
rustc 1.63.0-nightly (bb8c2f411 2022-06-19)
    let difficulty = 0x0fffffffffffffffffffffffffffffff;        
    //write!("{:X}","0x00000000fffffffffffffffffffffff");
    set_var("DIFFICULTY", "0x000fffffffffffffffffffffffffffff");
    let  difficulty_str=var_ret_difficulty("0x000fffffffffffffffffffffffffffff"); 
    
    let ed=difficulty_str.as_str().parse::<u128>().unwrap(); 
    let edb=u128_bytes(&ed);
    
    let ddb=difficulty_bytes_as_u128(&edb.to_vec());
    assert_eq!(ed,ddb);

Output:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ParseIntError { kind: InvalidDigit }'

Here's how I would parse the string (Rust Playground):

fn main() {
    let difficulty_str = "0x000fffffffffffffffffffffffffffff".to_string();
    let ed: &str = difficulty_str.strip_prefix("0x").unwrap();
    let ed: u128 = u128::from_str_radix(ed, 16).unwrap();
    let edb: [u8; 16] = ed.to_le_bytes();
    println!("{edb:x?}");
}
[ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, ff, f, 0]

Very Good I found another solution:
en-string is Ok but de-string need to consider more

    let  difficulty_str=var_ret_difficulty("0x000fffffffffffffffffffffffffffff"); 
    
    let mut difficulty_byte=difficulty_str.as_bytes();
    let difficulty_u128=read_ne_u128(&mut difficulty_byte);

    let difficulty=u128::from_ne_bytes(difficulty_u128.to_ne_bytes());
    assert_eq!(difficulty_u128,difficulty);


    
    let mut de_difficulty_byte=difficulty.to_ne_bytes();
    let de_difficulty_str=String::try_from(Box::new(&de_difficulty_byte));
    //let de_difficulty_str=std::str::from_utf8(&de_difficulty_byte).unwrap();

    
    //assert_eq!(de_difficulty_str_le,difficulty_str_le);


    println!("Printed:{:?} {:?}",de_difficulty_str,difficulty_str);

Output:

the trait bound `std::string::String: From<Box<&[u8; 16]>>` is not satisfied

How can I overcome the trait of "String::try_from"

For the other direction, you can use the format!() macro (Rust Playground):

fn main() {
    let diff_str = "0x000fffffffffffffffffffffffffffff".to_string();
    let diff_digits = diff_str.strip_prefix("0x").unwrap();
    let diff = u128::from_str_radix(diff_digits, 16).unwrap();
    let diff_bytes = diff.to_le_bytes();

    let de_diff_bytes = diff_bytes;
    let de_diff = u128::from_le_bytes(de_diff_bytes);
    let de_diff_str = format!("0x{de_diff:032x}");

    assert_eq!(diff_str, de_diff_str);
}
2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.