/rust/registry/src/index.crates.io-1949cf8c6b5b557f/aws-lc-rs-1.16.2/src/hex.rs
Line | Count | Source |
1 | | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
2 | | // SPDX-License-Identifier: Apache-2.0 OR ISC |
3 | | |
4 | | /// Converts bytes to a lower-case hex string |
5 | | #[allow(clippy::missing_panics_doc)] |
6 | 0 | pub fn encode<T: AsRef<[u8]>>(bytes: T) -> String { |
7 | 0 | let bytes = bytes.as_ref(); |
8 | 0 | let mut encoding = String::with_capacity(2 * bytes.len()); |
9 | 0 | for byte in bytes { |
10 | 0 | let upper_val = byte >> 4u8; |
11 | 0 | let lower_val = byte & 0x0f; |
12 | 0 | // DON'T PANIC: it shouldn't be possible to panic because only bottom 4 bits can be set. |
13 | 0 | encoding.push(char::from_digit(u32::from(upper_val), 16).unwrap()); |
14 | 0 | encoding.push(char::from_digit(u32::from(lower_val), 16).unwrap()); |
15 | 0 | } |
16 | 0 | encoding |
17 | 0 | } Unexecuted instantiation: aws_lc_rs::hex::encode::<[u8; 32]> Unexecuted instantiation: aws_lc_rs::hex::encode::<&aws_lc_rs::ed25519::PublicKey> Unexecuted instantiation: aws_lc_rs::hex::encode::<&[u8]> |
18 | | |
19 | | /// Converts bytes to an upper-case hex string |
20 | 0 | pub fn encode_upper<T: AsRef<[u8]>>(bytes: T) -> String { |
21 | 0 | encode(bytes).to_ascii_uppercase() |
22 | 0 | } |
23 | | |
24 | | /// Converts a hex string to a vector of bytes |
25 | | /// # Errors |
26 | | /// Returns an error if `hex_str` contains a non-hex digit. |
27 | | #[allow(clippy::missing_panics_doc)] |
28 | 0 | pub fn decode(hex_str: &str) -> Result<Vec<u8>, String> { |
29 | 0 | let mut bytes = Vec::<u8>::with_capacity(hex_str.len() / 2 + 1); |
30 | 0 | let mut current_byte = b'\0'; |
31 | 0 | let mut index: u32 = 0; |
32 | 0 | for ch in hex_str.chars() { |
33 | 0 | if !ch.is_ascii_hexdigit() { |
34 | 0 | return Err("Invalid hex string".to_string()); |
35 | 0 | } |
36 | | #[allow(clippy::cast_possible_truncation)] |
37 | | // DON'T PANIC: it should not be possible to panic because we verify above that the character is a |
38 | | // hex digit. |
39 | 0 | let value = ch.to_digit(16).unwrap() as u8; |
40 | 0 | if index % 2 == 0 { |
41 | 0 | current_byte = value << 4; |
42 | 0 | } else { |
43 | 0 | current_byte |= value; |
44 | 0 | bytes.push(current_byte); |
45 | 0 | } |
46 | | |
47 | 0 | if let Some(idx) = index.checked_add(1) { |
48 | 0 | index = idx; |
49 | 0 | } else { |
50 | 0 | break; |
51 | | } |
52 | | } |
53 | 0 | if index % 2 == 1 { |
54 | 0 | bytes.push(current_byte); |
55 | 0 | } |
56 | 0 | Ok(bytes) |
57 | 0 | } |
58 | | |
59 | | /// Converts a hex string to a vector of bytes. |
60 | | /// It ignores any characters that are not valid hex digits. |
61 | | #[must_use] |
62 | | #[allow(clippy::missing_panics_doc)] |
63 | 0 | pub fn decode_dirty(hex_str: &str) -> Vec<u8> { |
64 | 0 | let clean: String = hex_str.chars().filter(char::is_ascii_hexdigit).collect(); |
65 | | // DON'T PANIC: it should not be possible to panic because we filter out all non-hex digits. |
66 | 0 | decode(clean.as_str()).unwrap() |
67 | 0 | } |