xref: /aosp_15_r20/external/cronet/third_party/rust/chromium_crates_io/vendor/hex-0.4.3/src/lib.rs (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2013-2014 The Rust Project Developers.
2 // Copyright (c) 2015-2020 The rust-hex Developers.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9 //! Encoding and decoding hex strings.
10 //!
11 //! For most cases, you can simply use the [`decode`], [`encode`] and
12 //! [`encode_upper`] functions. If you need a bit more control, use the traits
13 //! [`ToHex`] and [`FromHex`] instead.
14 //!
15 //! # Example
16 //!
17 //! ```
18 //! # #[cfg(not(feature = "alloc"))]
19 //! # let mut output = [0; 0x18];
20 //! #
21 //! # #[cfg(not(feature = "alloc"))]
22 //! # hex::encode_to_slice(b"Hello world!", &mut output).unwrap();
23 //! #
24 //! # #[cfg(not(feature = "alloc"))]
25 //! # let hex_string = ::core::str::from_utf8(&output).unwrap();
26 //! #
27 //! # #[cfg(feature = "alloc")]
28 //! let hex_string = hex::encode("Hello world!");
29 //!
30 //! println!("{}", hex_string); // Prints "48656c6c6f20776f726c6421"
31 //!
32 //! # assert_eq!(hex_string, "48656c6c6f20776f726c6421");
33 //! ```
34 
35 #![doc(html_root_url = "https://docs.rs/hex/0.4.3")]
36 #![cfg_attr(not(feature = "std"), no_std)]
37 #![cfg_attr(docsrs, feature(doc_cfg))]
38 #![allow(clippy::unreadable_literal)]
39 
40 #[cfg(feature = "alloc")]
41 extern crate alloc;
42 #[cfg(feature = "alloc")]
43 use alloc::{string::String, vec::Vec};
44 
45 use core::iter;
46 
47 mod error;
48 pub use crate::error::FromHexError;
49 
50 #[cfg(feature = "serde")]
51 #[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
52 pub mod serde;
53 #[cfg(feature = "serde")]
54 pub use crate::serde::deserialize;
55 #[cfg(all(feature = "alloc", feature = "serde"))]
56 pub use crate::serde::{serialize, serialize_upper};
57 
58 /// Encoding values as hex string.
59 ///
60 /// This trait is implemented for all `T` which implement `AsRef<[u8]>`. This
61 /// includes `String`, `str`, `Vec<u8>` and `[u8]`.
62 ///
63 /// # Example
64 ///
65 /// ```
66 /// use hex::ToHex;
67 ///
68 /// println!("{}", "Hello world!".encode_hex::<String>());
69 /// # assert_eq!("Hello world!".encode_hex::<String>(), "48656c6c6f20776f726c6421".to_string());
70 /// ```
71 ///
72 /// *Note*: instead of using this trait, you might want to use [`encode()`].
73 pub trait ToHex {
74     /// Encode the hex strict representing `self` into the result. Lower case
75     /// letters are used (e.g. `f9b4ca`)
encode_hex<T: iter::FromIterator<char>>(&self) -> T76     fn encode_hex<T: iter::FromIterator<char>>(&self) -> T;
77 
78     /// Encode the hex strict representing `self` into the result. Upper case
79     /// letters are used (e.g. `F9B4CA`)
encode_hex_upper<T: iter::FromIterator<char>>(&self) -> T80     fn encode_hex_upper<T: iter::FromIterator<char>>(&self) -> T;
81 }
82 
83 const HEX_CHARS_LOWER: &[u8; 16] = b"0123456789abcdef";
84 const HEX_CHARS_UPPER: &[u8; 16] = b"0123456789ABCDEF";
85 
86 struct BytesToHexChars<'a> {
87     inner: ::core::slice::Iter<'a, u8>,
88     table: &'static [u8; 16],
89     next: Option<char>,
90 }
91 
92 impl<'a> BytesToHexChars<'a> {
new(inner: &'a [u8], table: &'static [u8; 16]) -> BytesToHexChars<'a>93     fn new(inner: &'a [u8], table: &'static [u8; 16]) -> BytesToHexChars<'a> {
94         BytesToHexChars {
95             inner: inner.iter(),
96             table,
97             next: None,
98         }
99     }
100 }
101 
102 impl<'a> Iterator for BytesToHexChars<'a> {
103     type Item = char;
104 
next(&mut self) -> Option<Self::Item>105     fn next(&mut self) -> Option<Self::Item> {
106         match self.next.take() {
107             Some(current) => Some(current),
108             None => self.inner.next().map(|byte| {
109                 let current = self.table[(byte >> 4) as usize] as char;
110                 self.next = Some(self.table[(byte & 0x0F) as usize] as char);
111                 current
112             }),
113         }
114     }
115 
size_hint(&self) -> (usize, Option<usize>)116     fn size_hint(&self) -> (usize, Option<usize>) {
117         let length = self.len();
118         (length, Some(length))
119     }
120 }
121 
122 impl<'a> iter::ExactSizeIterator for BytesToHexChars<'a> {
len(&self) -> usize123     fn len(&self) -> usize {
124         let mut length = self.inner.len() * 2;
125         if self.next.is_some() {
126             length += 1;
127         }
128         length
129     }
130 }
131 
132 #[inline]
encode_to_iter<T: iter::FromIterator<char>>(table: &'static [u8; 16], source: &[u8]) -> T133 fn encode_to_iter<T: iter::FromIterator<char>>(table: &'static [u8; 16], source: &[u8]) -> T {
134     BytesToHexChars::new(source, table).collect()
135 }
136 
137 impl<T: AsRef<[u8]>> ToHex for T {
encode_hex<U: iter::FromIterator<char>>(&self) -> U138     fn encode_hex<U: iter::FromIterator<char>>(&self) -> U {
139         encode_to_iter(HEX_CHARS_LOWER, self.as_ref())
140     }
141 
encode_hex_upper<U: iter::FromIterator<char>>(&self) -> U142     fn encode_hex_upper<U: iter::FromIterator<char>>(&self) -> U {
143         encode_to_iter(HEX_CHARS_UPPER, self.as_ref())
144     }
145 }
146 
147 /// Types that can be decoded from a hex string.
148 ///
149 /// This trait is implemented for `Vec<u8>` and small `u8`-arrays.
150 ///
151 /// # Example
152 ///
153 /// ```
154 /// use core::str;
155 /// use hex::FromHex;
156 ///
157 /// let buffer = <[u8; 12]>::from_hex("48656c6c6f20776f726c6421")?;
158 /// let string = str::from_utf8(&buffer).expect("invalid buffer length");
159 ///
160 /// println!("{}", string); // prints "Hello world!"
161 /// # assert_eq!("Hello world!", string);
162 /// # Ok::<(), hex::FromHexError>(())
163 /// ```
164 pub trait FromHex: Sized {
165     type Error;
166 
167     /// Creates an instance of type `Self` from the given hex string, or fails
168     /// with a custom error type.
169     ///
170     /// Both, upper and lower case characters are valid and can even be
171     /// mixed (e.g. `f9b4ca`, `F9B4CA` and `f9B4Ca` are all valid strings).
from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error>172     fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error>;
173 }
174 
val(c: u8, idx: usize) -> Result<u8, FromHexError>175 fn val(c: u8, idx: usize) -> Result<u8, FromHexError> {
176     match c {
177         b'A'..=b'F' => Ok(c - b'A' + 10),
178         b'a'..=b'f' => Ok(c - b'a' + 10),
179         b'0'..=b'9' => Ok(c - b'0'),
180         _ => Err(FromHexError::InvalidHexCharacter {
181             c: c as char,
182             index: idx,
183         }),
184     }
185 }
186 
187 #[cfg(feature = "alloc")]
188 impl FromHex for Vec<u8> {
189     type Error = FromHexError;
190 
from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error>191     fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
192         let hex = hex.as_ref();
193         if hex.len() % 2 != 0 {
194             return Err(FromHexError::OddLength);
195         }
196 
197         hex.chunks(2)
198             .enumerate()
199             .map(|(i, pair)| Ok(val(pair[0], 2 * i)? << 4 | val(pair[1], 2 * i + 1)?))
200             .collect()
201     }
202 }
203 
204 // Helper macro to implement the trait for a few fixed sized arrays. Once Rust
205 // has type level integers, this should be removed.
206 macro_rules! from_hex_array_impl {
207     ($($len:expr)+) => {$(
208         impl FromHex for [u8; $len] {
209             type Error = FromHexError;
210 
211             fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, Self::Error> {
212                 let mut out = [0_u8; $len];
213                 decode_to_slice(hex, &mut out as &mut [u8])?;
214                 Ok(out)
215             }
216         }
217     )+}
218 }
219 
220 from_hex_array_impl! {
221     1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
222     17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
223     33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
224     49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
225     65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
226     81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
227     97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
228     113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
229     160 192 200 224 256 384 512 768 1024 2048 4096 8192 16384 32768
230 }
231 
232 #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
233 from_hex_array_impl! {
234     65536 131072 262144 524288 1048576 2097152 4194304 8388608
235     16777216 33554432 67108864 134217728 268435456 536870912
236     1073741824 2147483648
237 }
238 
239 #[cfg(target_pointer_width = "64")]
240 from_hex_array_impl! {
241     4294967296
242 }
243 
244 /// Encodes `data` as hex string using lowercase characters.
245 ///
246 /// Lowercase characters are used (e.g. `f9b4ca`). The resulting string's
247 /// length is always even, each byte in `data` is always encoded using two hex
248 /// digits. Thus, the resulting string contains exactly twice as many bytes as
249 /// the input data.
250 ///
251 /// # Example
252 ///
253 /// ```
254 /// assert_eq!(hex::encode("Hello world!"), "48656c6c6f20776f726c6421");
255 /// assert_eq!(hex::encode(vec![1, 2, 3, 15, 16]), "0102030f10");
256 /// ```
257 #[must_use]
258 #[cfg(feature = "alloc")]
encode<T: AsRef<[u8]>>(data: T) -> String259 pub fn encode<T: AsRef<[u8]>>(data: T) -> String {
260     data.encode_hex()
261 }
262 
263 /// Encodes `data` as hex string using uppercase characters.
264 ///
265 /// Apart from the characters' casing, this works exactly like `encode()`.
266 ///
267 /// # Example
268 ///
269 /// ```
270 /// assert_eq!(hex::encode_upper("Hello world!"), "48656C6C6F20776F726C6421");
271 /// assert_eq!(hex::encode_upper(vec![1, 2, 3, 15, 16]), "0102030F10");
272 /// ```
273 #[must_use]
274 #[cfg(feature = "alloc")]
encode_upper<T: AsRef<[u8]>>(data: T) -> String275 pub fn encode_upper<T: AsRef<[u8]>>(data: T) -> String {
276     data.encode_hex_upper()
277 }
278 
279 /// Decodes a hex string into raw bytes.
280 ///
281 /// Both, upper and lower case characters are valid in the input string and can
282 /// even be mixed (e.g. `f9b4ca`, `F9B4CA` and `f9B4Ca` are all valid strings).
283 ///
284 /// # Example
285 ///
286 /// ```
287 /// assert_eq!(
288 ///     hex::decode("48656c6c6f20776f726c6421"),
289 ///     Ok("Hello world!".to_owned().into_bytes())
290 /// );
291 ///
292 /// assert_eq!(hex::decode("123"), Err(hex::FromHexError::OddLength));
293 /// assert!(hex::decode("foo").is_err());
294 /// ```
295 #[cfg(feature = "alloc")]
decode<T: AsRef<[u8]>>(data: T) -> Result<Vec<u8>, FromHexError>296 pub fn decode<T: AsRef<[u8]>>(data: T) -> Result<Vec<u8>, FromHexError> {
297     FromHex::from_hex(data)
298 }
299 
300 /// Decode a hex string into a mutable bytes slice.
301 ///
302 /// Both, upper and lower case characters are valid in the input string and can
303 /// even be mixed (e.g. `f9b4ca`, `F9B4CA` and `f9B4Ca` are all valid strings).
304 ///
305 /// # Example
306 ///
307 /// ```
308 /// let mut bytes = [0u8; 4];
309 /// assert_eq!(hex::decode_to_slice("6b697769", &mut bytes as &mut [u8]), Ok(()));
310 /// assert_eq!(&bytes, b"kiwi");
311 /// ```
decode_to_slice<T: AsRef<[u8]>>(data: T, out: &mut [u8]) -> Result<(), FromHexError>312 pub fn decode_to_slice<T: AsRef<[u8]>>(data: T, out: &mut [u8]) -> Result<(), FromHexError> {
313     let data = data.as_ref();
314 
315     if data.len() % 2 != 0 {
316         return Err(FromHexError::OddLength);
317     }
318     if data.len() / 2 != out.len() {
319         return Err(FromHexError::InvalidStringLength);
320     }
321 
322     for (i, byte) in out.iter_mut().enumerate() {
323         *byte = val(data[2 * i], 2 * i)? << 4 | val(data[2 * i + 1], 2 * i + 1)?;
324     }
325 
326     Ok(())
327 }
328 
329 // generates an iterator like this
330 // (0, 1)
331 // (2, 3)
332 // (4, 5)
333 // (6, 7)
334 // ...
335 #[inline]
generate_iter(len: usize) -> impl Iterator<Item = (usize, usize)>336 fn generate_iter(len: usize) -> impl Iterator<Item = (usize, usize)> {
337     (0..len).step_by(2).zip((0..len).skip(1).step_by(2))
338 }
339 
340 // the inverse of `val`.
341 #[inline]
342 #[must_use]
byte2hex(byte: u8, table: &[u8; 16]) -> (u8, u8)343 fn byte2hex(byte: u8, table: &[u8; 16]) -> (u8, u8) {
344     let high = table[((byte & 0xf0) >> 4) as usize];
345     let low = table[(byte & 0x0f) as usize];
346 
347     (high, low)
348 }
349 
350 /// Encodes some bytes into a mutable slice of bytes.
351 ///
352 /// The output buffer, has to be able to hold at least `input.len() * 2` bytes,
353 /// otherwise this function will return an error.
354 ///
355 /// # Example
356 ///
357 /// ```
358 /// # use hex::FromHexError;
359 /// # fn main() -> Result<(), FromHexError> {
360 /// let mut bytes = [0u8; 4 * 2];
361 ///
362 /// hex::encode_to_slice(b"kiwi", &mut bytes)?;
363 /// assert_eq!(&bytes, b"6b697769");
364 /// # Ok(())
365 /// # }
366 /// ```
encode_to_slice<T: AsRef<[u8]>>(input: T, output: &mut [u8]) -> Result<(), FromHexError>367 pub fn encode_to_slice<T: AsRef<[u8]>>(input: T, output: &mut [u8]) -> Result<(), FromHexError> {
368     if input.as_ref().len() * 2 != output.len() {
369         return Err(FromHexError::InvalidStringLength);
370     }
371 
372     for (byte, (i, j)) in input
373         .as_ref()
374         .iter()
375         .zip(generate_iter(input.as_ref().len() * 2))
376     {
377         let (high, low) = byte2hex(*byte, HEX_CHARS_LOWER);
378         output[i] = high;
379         output[j] = low;
380     }
381 
382     Ok(())
383 }
384 
385 #[cfg(test)]
386 mod test {
387     use super::*;
388     #[cfg(feature = "alloc")]
389     use alloc::string::ToString;
390     use pretty_assertions::assert_eq;
391 
392     #[test]
393     #[cfg(feature = "alloc")]
test_gen_iter()394     fn test_gen_iter() {
395         let result = vec![(0, 1), (2, 3)];
396 
397         assert_eq!(generate_iter(5).collect::<Vec<_>>(), result);
398     }
399 
400     #[test]
test_encode_to_slice()401     fn test_encode_to_slice() {
402         let mut output_1 = [0; 4 * 2];
403         encode_to_slice(b"kiwi", &mut output_1).unwrap();
404         assert_eq!(&output_1, b"6b697769");
405 
406         let mut output_2 = [0; 5 * 2];
407         encode_to_slice(b"kiwis", &mut output_2).unwrap();
408         assert_eq!(&output_2, b"6b69776973");
409 
410         let mut output_3 = [0; 100];
411 
412         assert_eq!(
413             encode_to_slice(b"kiwis", &mut output_3),
414             Err(FromHexError::InvalidStringLength)
415         );
416     }
417 
418     #[test]
test_decode_to_slice()419     fn test_decode_to_slice() {
420         let mut output_1 = [0; 4];
421         decode_to_slice(b"6b697769", &mut output_1).unwrap();
422         assert_eq!(&output_1, b"kiwi");
423 
424         let mut output_2 = [0; 5];
425         decode_to_slice(b"6b69776973", &mut output_2).unwrap();
426         assert_eq!(&output_2, b"kiwis");
427 
428         let mut output_3 = [0; 4];
429 
430         assert_eq!(
431             decode_to_slice(b"6", &mut output_3),
432             Err(FromHexError::OddLength)
433         );
434     }
435 
436     #[test]
437     #[cfg(feature = "alloc")]
test_encode()438     fn test_encode() {
439         assert_eq!(encode("foobar"), "666f6f626172");
440     }
441 
442     #[test]
443     #[cfg(feature = "alloc")]
test_decode()444     fn test_decode() {
445         assert_eq!(
446             decode("666f6f626172"),
447             Ok(String::from("foobar").into_bytes())
448         );
449     }
450 
451     #[test]
452     #[cfg(feature = "alloc")]
test_from_hex_okay_str()453     pub fn test_from_hex_okay_str() {
454         assert_eq!(Vec::from_hex("666f6f626172").unwrap(), b"foobar");
455         assert_eq!(Vec::from_hex("666F6F626172").unwrap(), b"foobar");
456     }
457 
458     #[test]
459     #[cfg(feature = "alloc")]
test_from_hex_okay_bytes()460     pub fn test_from_hex_okay_bytes() {
461         assert_eq!(Vec::from_hex(b"666f6f626172").unwrap(), b"foobar");
462         assert_eq!(Vec::from_hex(b"666F6F626172").unwrap(), b"foobar");
463     }
464 
465     #[test]
466     #[cfg(feature = "alloc")]
test_invalid_length()467     pub fn test_invalid_length() {
468         assert_eq!(Vec::from_hex("1").unwrap_err(), FromHexError::OddLength);
469         assert_eq!(
470             Vec::from_hex("666f6f6261721").unwrap_err(),
471             FromHexError::OddLength
472         );
473     }
474 
475     #[test]
476     #[cfg(feature = "alloc")]
test_invalid_char()477     pub fn test_invalid_char() {
478         assert_eq!(
479             Vec::from_hex("66ag").unwrap_err(),
480             FromHexError::InvalidHexCharacter { c: 'g', index: 3 }
481         );
482     }
483 
484     #[test]
485     #[cfg(feature = "alloc")]
test_empty()486     pub fn test_empty() {
487         assert_eq!(Vec::from_hex("").unwrap(), b"");
488     }
489 
490     #[test]
491     #[cfg(feature = "alloc")]
test_from_hex_whitespace()492     pub fn test_from_hex_whitespace() {
493         assert_eq!(
494             Vec::from_hex("666f 6f62617").unwrap_err(),
495             FromHexError::InvalidHexCharacter { c: ' ', index: 4 }
496         );
497     }
498 
499     #[test]
test_from_hex_array()500     pub fn test_from_hex_array() {
501         assert_eq!(
502             <[u8; 6] as FromHex>::from_hex("666f6f626172"),
503             Ok([0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72])
504         );
505 
506         assert_eq!(
507             <[u8; 5] as FromHex>::from_hex("666f6f626172"),
508             Err(FromHexError::InvalidStringLength)
509         );
510     }
511 
512     #[test]
513     #[cfg(feature = "alloc")]
test_to_hex()514     fn test_to_hex() {
515         assert_eq!(
516             [0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72].encode_hex::<String>(),
517             "666f6f626172".to_string(),
518         );
519 
520         assert_eq!(
521             [0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72].encode_hex_upper::<String>(),
522             "666F6F626172".to_string(),
523         );
524     }
525 }
526