Kuly14
Kuly14

Reputation: 608

How to convert [u8; 32] type to binary

I'm using a Sha256 hashing function that returns [u8; 32] because the 256 bit long hash is too big to be represented in Rust's native types.

That's all fine but I need to generate a binary number from the hash and check how many leading zeros are in the binary number.

Is there any good way to do this?

As of now, I tried to convert each separate u8 to its binary form and concatenate them together, but that doesn't generate the right number.

pub fn to_bits(arr: &[u8; 32]) -> String {
    let mut final_str = String::new();
    for i in arr {
        final_str.push_str(&format!("{:b}", i));
    }

    final_str
}

Upvotes: 0

Views: 1345

Answers (1)

bk2204
bk2204

Reputation: 76509

You can actually do this without needing to convert it into another form. Each byte can be inspected for its leading zero bits with u8::leading_zeros, so you could write something like this (tests included):

pub fn leading_bits(arr: &[u8; 32]) -> u32 {
    let mut count = 0;
    for x in arr {
        let bits = x.leading_zeros();
        count += bits;
        if bits != 8 {
            break;
        }
    }
    count
}

#[cfg(test)]
mod tests {
    use super::leading_bits;

    #[test]
    fn test_leading_bits() {
        assert_eq!(leading_bits(&[0u8; 32]), 256);
        assert_eq!(leading_bits(&[1u8; 32]), 7);
        let mut buf = [0u8; 32];
        buf[1] = 0x80;
        assert_eq!(leading_bits(&buf), 8);
        buf[1] = 0x00;
        buf[2] = 0x0f;
        assert_eq!(leading_bits(&buf), 20);
    }
}

We look at each byte in turn. If a byte has less than 8 leading zeros in it, then we've seen at least one 1, so break out of the loop.

Upvotes: 5

Related Questions