1use super::{
40 Encoding,
41 Error::{self, *},
42};
43#[cfg(feature = "alloc")]
44use alloc::vec::Vec;
45
46#[cfg(feature = "alloc")]
48pub fn encode<B: AsRef<[u8]>>(bytes: B) -> Vec<u8> {
49 Hex::lower_case().encode(bytes)
50}
51
52#[cfg(feature = "alloc")]
55pub fn decode<B: AsRef<[u8]>>(encoded_bytes: B) -> Result<Vec<u8>, Error> {
56 Hex::lower_case().decode(encoded_bytes)
57}
58
59#[cfg(feature = "alloc")]
61pub fn encode_upper<B: AsRef<[u8]>>(bytes: B) -> Vec<u8> {
62 Hex::upper_case().encode(bytes)
63}
64
65#[cfg(feature = "alloc")]
68pub fn decode_upper<B: AsRef<[u8]>>(encoded_bytes: B) -> Result<Vec<u8>, Error> {
69 Hex::upper_case().decode(encoded_bytes)
70}
71
72#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq, PartialOrd, Ord)]
74pub struct Hex {
75 case: Case,
77}
78
79impl Hex {
80 pub fn lower_case() -> Hex {
82 Hex { case: Case::Lower }
83 }
84
85 pub fn upper_case() -> Hex {
87 Hex { case: Case::Upper }
88 }
89}
90
91impl Encoding for Hex {
92 fn encode_to_slice(&self, src: &[u8], dst: &mut [u8]) -> Result<usize, Error> {
93 if self.encoded_len(src) > dst.len() {
94 return Err(LengthInvalid);
95 }
96
97 for (i, src_byte) in src.iter().enumerate() {
98 let offset = i * 2;
99 dst[offset] = self.case.encode_nibble(src_byte >> 4);
100 dst[offset + 1] = self.case.encode_nibble(src_byte & 0x0f);
101 }
102
103 Ok(src.len() * 2)
104 }
105
106 fn encoded_len(&self, bytes: &[u8]) -> usize {
107 bytes.len() * 2
108 }
109
110 fn decode_to_slice(&self, src: &[u8], dst: &mut [u8]) -> Result<usize, Error> {
111 if !src.is_empty() && char::from(src[src.len() - 1]).is_whitespace() {
113 return Err(TrailingWhitespace);
114 }
115
116 let dst_length = self.decoded_len(src)?;
117 ensure!(dst_length <= dst.len(), LengthInvalid);
118
119 let mut err: usize = 0;
120
121 for (i, dst_byte) in dst.iter_mut().enumerate().take(dst_length) {
122 let src_offset = i * 2;
123 let byte = (self.case.decode_nibble(src[src_offset]) << 4)
124 | self.case.decode_nibble(src[src_offset + 1]);
125 err |= byte >> 8;
126 *dst_byte = byte as u8;
127 }
128
129 if err == 0 {
130 Ok(dst_length)
131 } else {
132 Err(EncodingInvalid)
133 }
134 }
135
136 fn decoded_len(&self, bytes: &[u8]) -> Result<usize, Error> {
137 if bytes.len() & 1 == 0 {
138 Ok(bytes.len() >> 1)
139 } else {
140 Err(LengthInvalid)
141 }
142 }
143}
144
145#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
147enum Case {
148 Lower,
149 Upper,
150}
151
152impl Case {
153 #[inline]
155 fn decode_nibble(self, src: u8) -> usize {
156 let byte = src as isize;
159 let mut ret: isize = -1;
160
161 ret += (((0x2fisize - byte) & (byte - 0x3a)) >> 8) & (byte - 47);
164
165 ret += match self {
166 Case::Lower => {
167 (((0x60isize - byte) & (byte - 0x67)) >> 8) & (byte - 86)
170 }
171 Case::Upper => {
172 (((0x40isize - byte) & (byte - 0x47)) >> 8) & (byte - 54)
175 }
176 };
177
178 ret as usize
179 }
180
181 #[inline]
183 fn encode_nibble(self, src: u8) -> u8 {
184 let mut ret = src as isize + 0x30;
185
186 ret += match self {
187 Case::Lower => {
188 ((0x39isize - ret) >> 8) & (0x61isize - 0x3a)
191 }
192 Case::Upper => {
193 ((0x39isize - ret) >> 8) & (0x41isize - 0x3a)
196 }
197 };
198
199 ret as u8
200 }
201}
202
203impl Default for Case {
204 fn default() -> Case {
206 Case::Lower
207 }
208}
209
210#[cfg(test)]
211mod tests {
212 use super::*;
213 use crate::error::Error::*;
214
215 struct HexVector {
217 raw: &'static [u8],
219
220 hex: &'static [u8],
222 }
223
224 const HEX_TEST_VECTORS: &[HexVector] = &[
225 HexVector { raw: b"", hex: b"" },
226 HexVector {
227 raw: b"\0",
228 hex: b"00",
229 },
230 HexVector {
231 raw: b"***",
232 hex: b"2a2a2a",
233 },
234 HexVector {
235 raw: b"\x01\x02\x03\x04",
236 hex: b"01020304",
237 },
238 HexVector {
239 raw: b"\xAD\xAD\xAD\xAD\xAD",
240 hex: b"adadadadad",
241 },
242 HexVector {
243 raw: b"\xFF\xFF\xFF\xFF\xFF",
244 hex: b"ffffffffff",
245 },
246 ];
247
248 #[test]
249 fn encode_test_vectors() {
250 for vector in HEX_TEST_VECTORS {
251 let mut out = [0u8; 10];
253 let out_len = Hex::lower_case()
254 .encode_to_slice(vector.raw, &mut out)
255 .unwrap();
256
257 assert_eq!(vector.hex, &out[..out_len]);
258 }
259 }
260
261 #[test]
262 fn decode_test_vectors() {
263 for vector in HEX_TEST_VECTORS {
264 let mut out = [0u8; 5];
266 let out_len = Hex::lower_case()
267 .decode_to_slice(vector.hex, &mut out)
268 .unwrap();
269
270 assert_eq!(vector.raw, &out[..out_len]);
271 }
272 }
273
274 #[test]
275 fn reject_odd_size_input() {
276 let mut out = [0u8; 3];
277 assert_eq!(
278 LengthInvalid,
279 Hex::lower_case()
280 .decode_to_slice(b"12345", &mut out)
281 .err()
282 .unwrap(),
283 )
284 }
285
286 #[test]
287 fn encode_and_decode_various_lengths() {
288 let data = [b'X'; 64];
289
290 for i in 0..data.len() {
291 let encoded = Hex::lower_case().encode(&data[..i]);
292
293 let decoded = Hex::lower_case().decode(encoded).unwrap();
295
296 assert_eq!(decoded.as_slice(), &data[..i]);
297 }
298 }
299}